Ir para conteúdo
Fórum Script Brasil
  • 0

Programa só pausa se eu usar 2 getchar();


princknoby

Pergunta

Olá a todos
Estou tentando parar de usar o system("pause"); pois li que ele pode ser bem inseguro e desnecessário de ser usado para pausar o console. 
Comecei a programa em Linux faz 3 dias, e de cara percebi que system("pause") aqui não funciona, então fui pesquisar, e foi assim que descobri os problemas em usar system("qualquer_coisa"); 

 

Então pesquisando bastante descobri que devo usar getchar(); ou getch(); o problema é que getch(); não funciona aqui no linux também (ao menos aqui deu erro), o único que funcionou aqui foi o getchar(); mas com uma ressalva, eu preciso usar o mesmo duas vezes (irei postar o código), eu queria saber se existe alguma solução pra isso, queria pausar o console para o usuário pressionar alguma tecla, e que isso funcionasse tanto no linux quanto no windows. 
Será que alguém poderia me ajudar?? 

Podem desconsiderar o que o programa precisa fazer, creio que não seja relevante, única parte que estou com dificuldade é a parte do getchar();

CÓDIGO:

#include <stdio.h>
#define TAM 2

void pause ()
{
    printf ("\nAperte a tecla [ENTER] para encerrar . . .");
    getchar(); //MEU PROBLEMA ESTA AQUI
    getchar();//SE EU DEIXAR APENAS 1 GETCHAR(); O PROGRAMA não PAUSA 
}

int main ()
{

    int m[TAM][TAM], l, c, x;

    for (l = 0; l < TAM; l++)
    {
        for (c = 0; c < TAM; c++)
        {
            printf ("Digite LINHA[%d] COLUNA[%d]: ", l, c);
            scanf ("%d", &m[l][c]);
        }
      printf ("\n");
    }

    printf ("\nDigite qualquer valor: ");
    scanf ("%d", &x);

    for (l = 0; l < TAM; l++)
    {
        for (c = 0; c < TAM; c++)
        {
            if (x == m[l][c])
            {
                printf ("\nO valor se encontra na matriz!\n");
                printf ("Ele esta na posicao: LINHA[%d] COLUNA[%d]\n\n", l, c);
                pause();
                return 0;
            }
        }
    }

    printf ("\nO valor não esta presente na matriz!\n\n");

    pause();
    return 0;
}

 

Obrigado

Editado por princknoby
Correções
Link para o comentário
Compartilhar em outros sites

9 respostass a esta questão

Posts Recomendados

  • 0

Achei algo interessante pesquisando ainda mais um pouco...
Achei uma forma de limpar o buffer que não consegui achar muitas críticas contra..

Coloquei o comando setbuf(stdin,NULL) antes do getchar(); e ai eu consegui usar apenas um getchar(); e rodou tudo certo.

 

Esse comando setbuf(stdin,NULL) é recomendado? Depois das coisas que li na gringa criticando o system("pause") fiquei até traumatizado, a rapaziada lá criticou de tudo que eu conheço kkkk
Então acabou que era tudo que agora to ficando com o pé atrás com todos esses comandos.

Seria essa uma solução viável e segura?

Obrigado.

Link para o comentário
Compartilhar em outros sites

  • 0

Olá @princknoby Você pode fazer uso de uma função como essa que vou passar, que não necessita de incluir nenhum arquivo de cabeçalho (biblioteca) em seu código. Seria essa:

void pausa() {
    printf("Pressione qualquer tecla para continuar...");
    scanf("%*c"); // lê um tecla qualquer e descarta o valor dela
}

Quanto a usar o comando setbuf(stind, NULL); eu não recomendo. Creio que uma função como esse q estou passando é muito mais útil

Outro problema que tem em seu código é a sujeira no buffer do teclado, para resolver isso pode fazer uso de uma função como essa:

void limpa_linha() {
    scanf("%*[^\n]");
    scanf("%*c");
}

Ou mesmo essa:

void fflush_stdin() {
    int ch;
    while ((ch = getchar()) != '\n' && ch != EOF);
}

O que ocorre em seu código que não pausa usando apenas um getchar() é que existe sujeira no buffer que seria basicamente lixo no buffer. Esse "lixo" é lido por um getchar() e por isso é que não pausa

Use uma dessas funções para limpar o buffer do teclado (stdin) e vai ver que usando apenas um comando getchar() o problema é resolvido

Para usar essas funções (qualquer uma delas) seria fazer a chamada da função após cada scanf. Seria isso:

 

for (c = 0; c < TAM; c++)
{
    printf ("Digite LINHA[%d] COLUNA[%d]: ", l, c);
    scanf ("%d", &m[l][c]);
    limpa_linha(); // ou fflush_stdin();
}

Para saber mais a respeito desse assunto recomendo essa aula:

Limpar o Buffer do teclado

Mas nessa aula também é indicada a função setbuf(stdin, NULL); e a mesma não é recomendada para limpar o buffer do teclado

Faça uso de uma das funções que passei acima 😊

 

Editado por Visitante
Atualizar comentário
Link para o comentário
Compartilhar em outros sites

  • 0
7 horas atrás, giu_d_ disse:

Olá @princknoby Você pode fazer uso de uma função como essa que vou passar, que não necessita de incluir nenhum arquivo de cabeçalho (biblioteca) em seu código. Seria essa:


void pausa() {
    printf("Pressione qualquer tecla para continuar...");
    scanf("%*c"); // lê um tecla qualquer e descarta o valor dela
}

Quanto a usar o comando setbuf(stind, NULL); eu não recomendo. Creio que uma função como esse q estou passando é muito mais útil

Outro problema que tem em seu código é a sujeira no buffer do teclado, para resolver isso pode fazer uso de uma função como essa:


void limpa_linha() {
    scanf("%*[^\n]");
    scanf("%*c");
}

Ou mesmo essa:


void fflush_stdin() {
    int ch;
    while ((ch = getchar()) != '\n' && ch != EOF);
}

O que ocorre em seu código que não pausa usando apenas um getchar() é que existe sujeira no buffer que seria basicamente lixo no buffer. Esse "lixo" é lido por um getchar() e por isso é que não pausa

Use uma dessas funções para limpar o buffer do teclado (stdin) e vai ver que usando apenas um comando getchar() o problema é resolvido

Para usar essas funções (qualquer uma delas) seria fazer a chamada da função após cada scanf. Seria isso:

 


for (c = 0; c < TAM; c++)
{
    printf ("Digite LINHA[%d] COLUNA[%d]: ", l, c);
    scanf ("%d", &m[l][c]);
    limpa_linha(); // ou fflush_stdin();
}

Para saber mais a respeito desse assunto recomendo essa aula:

Limpar o Buffer do teclado

Mas nessa aula também é indicada a função setbuf(stdin, NULL); e a mesma não é recomendada para limpar o buffer do teclado

Faça uso de uma das funções que passei acima 😊

 

Olá @giu_d_ me perdoe se eu soar abusado em te pedir ajuda mais uma vez... Mas me deparei com uma situação que não consegui encontrar nada na internet.

A função que você me ensinou está me servindo muito bem!
Mas me deparei com a seguinte situação:   E quando não houver nada no buffer para ser 'consumido' ou 'limpo'?
Como por exemplo nesse programa:

Código:

#include <stdio.h>
#define TAM 10

void pausar ()
{    
    int ch;
    while((ch = fgetc(stdin)) != EOF && ch != '\n');
    printf ("\nPress any key to continue . . .");
    scanf("%*c");//não PRECISO LIMPAR O BUFFER porque O USUARIO não VAI DIGITAR NADA
}

int main ()
{
    int m[TAM][TAM], i, j;

    for (i = 0; i < TAM; i++)
    {
        for (j = 0; j < TAM; j++)
        {
            if (i < j)
            {
                m[i][j] = 2*i + 7*j -2;//2i + 7j − 2 se i < j
            }

            else if (i == j)
            {
                m[i][j] = 3*(i*i) - 1; //3i² − 1 se i = j;
            }

            else if(i > j)
            {
                m[i][j] = 4*(i*i*i) - 5*(j*j) + 1; //4i³ − 5j 2 + 1 se i > j
            }
        }
    }

    printf ("\nMATRIZ:\n");
    for(i = 0; i < TAM; i++)
    {
        for (j = 0; j < TAM; j++)
        {
            printf ("%d\t", m[i][j]);
        }
      printf ("\n");
    }

    pausar ();
    return 0;
}

 

Ao termino desse programa eu estou tendo que pressionar alguma tecla, creio eu que para preencher o buffer com algo para ser limpo..
Como fica essa situação? Ante de escrever o código eu devo sabe se vou ter algo pra precisar limpar? Ou existe alguma forma de verificar se existe algo para ser limpo, e se não existir avançar para próxima etapa, que seria a 'pausa' do programa?

Mais uma vez, muito obrigado! 😄

Editado por princknoby
Correções
Link para o comentário
Compartilhar em outros sites

  • 0

Ei @giu_d_ acho que só agora entendi o motivo de você ter me recomendado chamar a função de limpeza após os scanf's
Sou bem iniciante, mas voltei ainda mais ao inicio pra tentar entender, fazendo programas ainda mais simples.

Eu passei a criar as funções separadas, uma pra limpeza, outra pra pausar, ai no caso, eu só chamo a função de limpeza caso meu programa tenha scanf, se não tiver é só não chamar, pois significa que o buffer estaria limpo, e ai só chamaria a função de pausa do console, ao final do programa.

Seria isso??

Link para o comentário
Compartilhar em outros sites

  • 0

Oĺá @princknoby Passei três funções, uma como o nome pausa() que seria apenas para pausar o programa e outras duas: limpa_linha() e fflush_stdin() que são para limpar o buffer do teclado

Criei um pequeno código, para mostrar como essas funções devem ser usadas:

#include <stdio.h>

#define TAM 3

// função para pausar o programa
void pausa() {
    printf("Pressione qualquer tecla para continuar...");
    scanf("%*c");
}

// função para limpar o buffer do teclado
void limpa_linha() {
    scanf("%*[^\n]");
    scanf("%*c");
}

int main() {

    int matriz[TAM][TAM], i, j;

    for (i = 0; i < TAM; i++) {
        for (j = 0; j < TAM; j++) {
            printf("Digite o valor para a posicao [%d][%d]: ", i, j);
            scanf("%d", &matriz[i][j]);
            limpa_linha(); // função para limpar o buffer do teclado
        }
    }

    pausa(); // função para pausar o programa, que equivale ao comando system("pause")

    for (i = 0; i < TAM; i++) {
        for (j = 0; j < TAM; j++) {
            printf("%2d ", matriz[i][j]);
        }
        printf("\n");
    }

    pausa(); // função para pausar o programa, que equivale ao comando system("pause")

    return 0;
}

Perceba que tem diferença entre as duas funções que estou usando no código. Uma é para limpar a sujeira do buffer e outra é apenas para pausar o programa

 São funções com objetivos bem distintos, é importante não confundir

Rodando esse código acima vai saber bem a diferença entre as duas

Se ainda ficar em dúvida sobre alguma coisa pode perguntar. ok?

A função para pausar o programa você pode usar em qualquer parte do código que quiser, já a função para limpar a sujeira do buffer deve ser chamada após ler um valor do teclado com o scanf, conforme mostrei acima

OBS: Também estou usando o Linux aqui. Linux Mint LMDE 3 😃

Editado por Visitante
Link para o comentário
Compartilhar em outros sites

  • 0

@princknoby Veja o exemplo mostrado na aula que está no link que passei. Para entender melhor a respeito da sujeira no buffer execute o programa chamando a função limpa_linha() depois do scanf e depois execute o mesmo programa sem a função limpa_linha()

#include <stdio.h>

void pausa() {
    printf("Pressione qualquer tecla para continuar...");
    scanf("%*c");
}

void limpa_linha() {
    scanf("%*[^\n]");
    scanf("%*c");
}

int main() {

    char ch;
    int i;

    for (i = 0; i < 5; i++) {
        printf("Digite o %da letra: ", i + 1);
        scanf("%c", &ch);
        limpa_linha(); // função para limpar o buffer do teclado
    }

    pausa(); // função para pausar o programa, que equivale ao comando system("pause")

    return 0;
}

Estou usando a função limpa_linha e não a função fflush_stdin apenas por gostar mais dessa função (limpa_linha)

Já se achar melhor a outra função que passei, fflush_stdin() pode usá-la normalmente. Ficaria assim o mesmo código:

#include <stdio.h>

// função para pausar o programa  
void pausa() {
    printf("Pressione qualquer tecla para continuar...");
    scanf("%*c");
}

// função para limpar a sujeira do buffer  
void fflush_stdin() {
    int ch;
    while ((ch = getchar()) != '\n' && ch != EOF);
}

int main() {

    char ch;
    int i;

    for (i = 0; i < 5; i++) {
        printf("Digite o %da letra: ", i + 1);
        scanf("%c", &ch);
        fflush_stdin(); // função para limpar o buffer do teclado
    }

    pausa(); // função para pausar o programa, que equivale ao comando system("pause") ou a função getchar()

    return 0;
}

Se ficar muito confuso para entender não se preocupe que é normal mesmo. O importante é saber que cada função tem uma finalidade específica

Só que é importante entender bem a respeito da sujeira no buffer e dos problemas que isso traz para um programa. E não só em C, mas também em C++ e Java (por exemplo)

Obs: Se é para ser sincero, tem muita gente que programa em Java já há algum tempo e ainda não sabe sobre a sujeira do buffer e os problemas que isso pode causar em um código

Editado por Visitante
Atualizar comentário
Link para o comentário
Compartilhar em outros sites

  • 0

Outro ponto: Se você usar uma das funções que passei acima para limpar a sujeira no buffer, vai ver que usando apenas um getchar() o programa vai parar (pausar) até que você pressione uma tecla

Veja nesse mesmo exemplo:

#include <stdio.h>

// função para limpar o buffer do teclado
void fflush_stdin() {
    int ch;
    while ((ch = getchar()) != '\n' && ch != EOF);
}

int main() {

    char ch;
    int i;

    for (i = 0; i < 5; i++) {
        printf("Digite o %da letra: ", i + 1);
        scanf("%c", &ch);
        fflush_stdin(); // função para limpar o buffer do teclado
    }

    getchar(); // função para pausar o programa

    return 0;
}

Não se preocupe muito agora em entender o que exatamente essas funções  para limpar o buffer do teclado que passei fazem. Ou seja, faça uso da qual achar melhor, pois com o tempo você vai entender bem a respeito da lógica dessas funções

Obs: Eu mesmo, quando estudava Java, não sabia dessa questão de sujeira no buffer. Só aprendi mesmo sobre isso quando comecei a estudar C

 

Editado por Visitante
Atualizar comentário
Link para o comentário
Compartilhar em outros sites

  • 0

@giu_d_ Não sei nem como te agradecer, obrigado por ter tirado o seu tempo pra me passar todas essas informações. 
Com sinceridade, a primeira vez que li as funções que me mandou, foi bem confuso mesmo, fiquei totalmente perdido e sem entender o que a função estava fazendo, só sabia qual seria o final, então aceitei o final e comecei a usá-las, e também comecei a ler sobre elas na internet. 

Ainda não entendi perfeitamente, mas agora estão bem mais claras pra mim, perto da primeira vez em que li o código, ainda mais agora depois das suas explicações.

Muito obrigado! :D 

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,4k
×
×
  • Criar Novo...