Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Boas Pessoal!
Já faz algum tempo que eu vejo pessoas postando códigos sempre com os mesmos errinhos, que acabam por virar vícios lá na frente.
Claro que é a maneira mais fácil de resolver a maioria dos problemas "chatos" que encontramos quando estamos programando em C/C++.
Mas não é a forma mais confiável, não é portável e ainda é deselegante.
Para já, o campeão, é o famoso std::system("pause").
Antes de mais, usem o Code::Blocks, não é preciso usar system("pause") para ver o resultado do seu programa!
O Problema...
system("pause");
Motivo
Eu imagino que é para conseguir ler o resultado do código, ou falar para o usuário: "Pressione qualquer tecla para continuar."
(Não consigo pensar em outros motivos...)
Como contornar?
Eu espero que vocês conheçam a função scanf().
Se vocês conhecem o nosso amigo scanf, então sabem que ele lê uma string que segue uma formatação.
Então chega de "blá blá blá", e vamos ao que interessa!
O uso do operador, " * " (supressão), na string de formatação, diz para o scanf ler e descartar qualquer coisa.
Como funciona?
int numero;
printf("Digite dois números separados por um espaço: ");
scanf("%*d %d", &numero);
O código acima pegará apenas o segundo número digitado, pois nós falamos para o scanf ler e descartar o primeiro.
Nós podemos fazer isso para qualquer tipo de dados.
Vamos então pedir ao scanf ler e descartar um caractére, uma quebra de linha ('\n').
//... tooooodo o seu código aqui
printf("Pressione enter para continuar");
scanf("%*c");Aproveitando a onda do scanf, vamos a um outro problema, que tem uma solução muuuuito parecida.
O Problema...
Sujeira no buffer de entrada, limpa com fflush(stdin)
Motivo
Essa é fácil, ninguém quer um código maluco, com '\n' de sobra em todo o lado.
Você nunca passou por esse problema??
Do it yourself! :P
int main()
{
char cont='s';
while(cont == 's')
{
printf("Deseja continuar? (s/n): ");
scanf("%c", &cont);
}
return 0;O que aconteceu aqui foi que quando digitamos 's' e apertamos enter, a string enviada foi "s\n", mas o scanf só leu o 's' e deixou o '\n' no buffer de entrada padrão (stdin), no próximo loop esse '\n' será lido automaticamente e vai sair do loop.
Como contornar?
Por que não devemos usar fflush(stdin) se ele "funciona" direito??
Na documentação da função está escrito: "effect undefined for input streams".
Se nem eles (que escreveram a função) sabem o que acontece, nós, simples mortais ^_^, muito menos!
Para resolver o problema, vamos de novo usar o operador de supressão do scanf.
e vamos falar para ele: "Hey, leia tuudo mas descarte o último caractére" (o último caractére sempre será um '\n').
Usando o mesmo código que gerou o problema:
int main()
{
char cont='s';
while(cont == 's')
{
printf("Deseja continuar? (s/n): ");
scanf("%c%*c", &cont); //note a mudança aqui!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}
return 0;
}Espero que tenha sanado algumas dúvidas dos iniciantes!
:lol:
Se gostarem eu fixo o tópico.
Até mais!
http://forum.imasters.com.br/public/style_emoticons/default/bye1.gif
Isis...
Fazer o que??
A esperança é a última que morre... rsrsrs
Sempre tem os trolhas, mas o aluno interessado não aprende a programar pelo professor.
Boa Victor é bastante util quem começa com C ler isso..
eu msm qnd vem gente perguntar falo pra usar o system..
soh uma coisa o : %*c pode ser colocado em qlqr lugar do scanf?
tipo:
scanf("%*c%c", &cont);
e
scanf("%c%*c", &cont);
[]s
QuitzAUMMM
Os livros não falam muito desse operador do scanf.
o operador pode ser usado em qualquer lugar, com qualquer tipo de dado, por exemplo:
dada uma string:
(teste1)(teste2)(teste3)
leia teste1 e teste3, e coloque em variáveis separadas, fazendo o uso de apenas 2 variáveis, uma para cada.
eu faria:
scanf("(%s)(%s)(%s)%c", &var1, &var2);
note que, a primeira ocorrência de ***** é para descartar a string que está ali, a segunda é para limpar o buffer de imediato...
Toda vez que eu uso scanf, eu ja adiciono "%*c" no final (quando não quero as quebras de linha).
Nota.: Isso funciona para as outras funções derivadas do scanf também, por exemplo: sscanf e fscanf
Ótimo tópico Victor.
Nunca tinha pensado em usar isso, já que aprendi usando o "fflush" e "system" .
Vlw pela dica, vô começar a usar ^_^
Tá mas ai tem o problema no substituto do stdin.
E quando eu não sei a qntidade de strings. Tipo tenho este código
//...
char str[50];
printf("Digite o nome: ");
scanf("%s",&str);Paulo, não entendi a sua dúvida.
se você não sabe o número de strings, e quer gravar os espaços na string, use fgets!!! ps.: ele manda o '\n' para a string também, deixando o buffer limpo
ou, deixando o scanf um pouco mais complicado:
scanf("%[^\n]%*c", &str);
Na verdade, a definição de string é cadeia de caractéres, do ingles, char array. Em C++ existe a classe std::string, que na verdade é um conjunto de métodos para facilitar o uso do char*.
E eu não encontrei a gambiarra... onde está?
se for usar fgets é soh depois você usar a magina do strlen-1 e do \0 e fim de papo ;D
Assim em momento algum eu quis desmerecer, mas a explicação, cobre o problema de ter uma string que tenha mais de um espaço (o que eu chamei de numro de strings), quanto ao trabalhar com array de char, sei lá é minha opinião de que fica um pouco... "complicação denecessária", mas ai é de cada um.
E o objetivo vou acrescentar com criticas construtivas, espero que isso tenha ficado claro e parabens pela iniciativa.
Já a respeito da classe std::string u a conhecia já mas não acho ela muiiito o que eu queria pois no fim usa char[] igual e não encapsula essas tarefas de array.
Mas paulo,
se não vamos trabalhar com array de chars, vamos trabalhar como?
Não esquecendo que estamos falando de C...
em C++ o nosso amigo std::cin nos resolve tudo! (ou quase tudo...hahahaha)
>
Mas paulo,
se não vamos trabalhar com array de chars, vamos trabalhar como?
Não esquecendo que estamos falando de C...
em C++ o nosso amigo std::cin nos resolve tudo! (ou quase tudo...hahahaha)
É neste ponto você tem razão, acho que estou querendo demais, tipo to viajando para classes, eu sei.
Mas concorda que seria bom?
Mais algumas razões para não usar system("pause") nem fflush(stdin):
a'\n'b'\n', o fflush vai limpar tudo depois do c, e não apenas o próximo '\n'. O segundo scanf do meu programa (supondo que ele possui dois scanfs para ler duas entradas char, tipo scanf ("%c", &var)) ficará comprometido e não lerá o caracter b.
Eu, por exemplo, as vezes redireciono o fluxo de entrada para um arquivo e o de saída para outro para facilitar os testes de entrada/saida de um algoritmo (apesar de que quase nunca eu programo).
Não que fflush seja uma função ruim, ela tem ótimos usos, mas esse não é um bom uso, visto que ele limita o uso de seu programa a receber dados apenas do teclado. Deixem pra usar fflush quando estiverem trabalhando com arquivos.
A solução proposto, que usa o * para descartar uma captura do fluxo, é uma solução mais adequada ao problema.
Vale lembrar que, apesar de vários scanf("%d", &var) sequênciais funcionarem perfeitamente, tal função não captura o '\n'. Logo, se usarmos um scanf ("%d", &var1) e logo após um scanf("%c", &var2), o segundo capturará o '\n' da stdin. o uso de um scanf("%d%*c", &var1) resolveria o problema.
Ah,fflush dá um warning quando usada com entradas pelo teclado (input streams). Porque eu não sei. Logo, até que alguém saiba porque essa função pode ter alguns comportamentos indefinidos e como evitar tais comportamentos, não usem fflush() a não ser para trabalhar com arquivos.
Como exemplo, considere o código a seguir:
/* problema com o scanf:
* ao realizar scanf com tipos diferentes, automaticamente a funcao le um '\n' vindo de uma scanf anterior que ainda permanecia no stdin
/
#include <stdio.h>
int main(void)
{
int a;
char b;
char c;
printf ("a: ");
scanf ("%d%*c", &a);
printf ("b: ");
scanf ("%c%*c", &b);
printf ("c: ");
scanf ("%c%*c", &c);
printf ("a = %d\n", a);
printf ("b = %c\n", b);
printf ("c = %c\n", c);
return 0;O primeiro scanf "está dizendo": captura um inteiro e ignora o caracter que vem depois do inteiro.
Logo, ela captura 85, salva em a, e ignora o '\n'.
Agora experimente entrar com um "ab", isto é, a stream ab'\n'.
Ela procura o inteiro a partir do a. Como a não é um caracter que pode representar um inteiro, a função scanf retorna, isso mesmo, continua o ab'\n' no stdin. O segundo scanf quer capturar um caracter e ignorar o próximo. Logo, ele captura o "a" e captura e ignora o "b", e ainda resta o "\n" no stdin. Tal "\n" será capturado pelo terceiro scanf.
O fato de não existir um outro caractere para ser ignorado (lembre-se que nosso último scanf captura 1 char e ignora o outro) não trará problemas, pois ao acabar o fluxo de entrada, o stdin, a função scanf retorna.
Resultado: Bacalhau!!!
Veja o que o cplusplus.com fala sobre a gets(): (A fgets eu não estudei ainda)
>
Reads characters from stdin and stores them as a string into str until a newline character ('\n') or the End-of-File is reached.
The ending newline character ('\n') is not included in the string.
A null character ('\0') is automatically appended after the last character copied to str to signal the end of the C string.
Notice that gets does not behave exactly as fgets does with stdin as argument: First, the ending newline character is not included with gets while with fgets it is. And second, gets does not let you specify a limit on how many characters are to be read, so you must be careful with the size of the array pointed by str to avoid buffer overflows.
cplusplus.com
Isso é, o '\n' é capturado, assim não precisamos ter que nos preocupar com ele no stdin. O '\n' é convertido para '\0' na string.Note que se a string for menor que a stream de entrada, a função gets ultrapassará os limites do array, ocorrendo assim uma operação perigosa ao sistema. Por isso é mais indicado o fgets(): não o uso porque eu não a estudei ainda, mas prefira fgets à gets.
Note o que o gcc me avisou quando eu criei um programa de teste para entender a gets antes de enviar este post:
gcc scanf.c -o scanf
/tmp/ccUDm33d.o: In function `main':
scanf.c:(.text+0x2f): warning: the `gets' function is dangerous and should not be used.
Bom pessoal, espero ter ajudado um pouco.
Vai uma dica: estudem e leiam livros, tentem compreender os conceitos para que não façam programas orientados a gambiarras!!!
Não adianta somente resolver o problema, resolvam corretamente, de forma eficiente e com um código bem escrito.
Não façam bacalhau, até porque manter e consertar um programa cheio de gambiarras custa muito mais do que desenvolver um programa bem feito!
po eu consegui entender a do system ("pause"), apliquei aqui e funcionou direito agora a do fflush nao to conseguindo implementar, se nao for abusar,teria como postar um programa que leia mas de 1 caracter usando fflush e esse mesmo programa nao usando ele?para eu poder entender a diferença?
#include<stdio.h>
int main(){
char a[5],B[5];
printf("digite a\n");
scanf("%s%*c",&a);
printf("digite b\n");
scanf("%s%*c",&B);
printf("%s,%s\n",a,B);
scanf("%*c");
return 0;
}
[http://forum.imasters.com.br/public/style_emoticons/](http://forum.imasters.com.br/public/style_emoticons/)default/thumbsup.gif esse daí le a string e limpa o lixo do buffer@fflush(stdin);
Isso é o que está na documentação:
**int fflush (FILE * stream);**
Libera o fluxo de fluxo e retorna zero em caso de sucesso ou EOF em caso de erro. Efeito indefinido para fluxo de entrada. fflush (NULL) libera todos os fluxos de saída.
Na documentação diz que pode gerar comportamento indefinido por se usar a função ? Eu posso estar enganado, mas o que eu entendi aí é que pode gerar efeito indefinido caso de um EOF. Talvez a execução do programa pare por conta disso levando a outros erros, mas talvez não. Nunca aconteceu comigo de o programa parar por causa dessa função. Talvez porquê eu usei elas nos lugares corretos. Tem razões para usar e para não usar. Como por exemplo, antes de um Scanf é legal usar, dentro do while. Já pra um redimencionamento para arquivo não é legal, como disse um user acima.
int i = 2
char nome[30];
while(i < 3)
{
printf("\n\tDigite seu nome: ");
if(nome != "") fflush(stdin); // Veriquei se a variável está vazia, se estiver não precisa do fflush(stdin)
gets(nome);
}
É trabalhoso ? É. É desnessário ? É. Visto que pode fazer um TOKEN.
Mas só estou falando que na minha humilde opinião, não tem porque não usar a função em determinados casos.
Interessante que só pode gerar um comportamento indefinido para fluxo de entrada, mas pra fluxo de saída não. Porque ?
E não pode usar a função gets() também né , vocês ficam bravos.
Caro Dee,
>
Na documentação diz que pode gerar comportamento indefinido por se usar a função ? Eu posso estar enganado, mas o que eu entendi aí é que pode gerar efeito indefinido caso de um EOF. Talvez a execução do programa pare por conta disso levando a outros erros, mas talvez não. Nunca aconteceu comigo de o programa parar por causa dessa função. Talvez porquê eu usei elas nos lugares corretos. Tem razões para usar e para não usar. Como por exemplo, antes de um Scanf é legal usar, dentro do while. Já pra um redimencionamento para arquivo não é legal, como disse um user acima.
Espero que você tenha lido o que eu escrevi no primeiro post, isto é, o meu artigo sobre o assunto.
Você não entendeu o que está escrito na documentação.
fflush RETORNA EOF no caso de ERRO.
O efeito é INDEFINIDO no caso de streams de ENTRADA.
>
Mas só estou falando que na minha humilde opinião, não tem porque não usar a função em determinados casos.
Se o efeito é INDEFINIDO, logo, não sabemos o que vai acontecer!Não é correto utilizar fflush(stdin) NUNCA, como está escrito na documentação! (fantástico não? está tudo no manual!)
E, a função gets...
A gente não fica bravo quando utiliza-se essa função, ficamos FURIOSOS!
Afinal, a função é vulnerável...
Leia o segundo post deste tópico
Abraços
http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif
>
Caro Dee,
>
Na documentação diz que pode gerar comportamento indefinido por se usar a função ? Eu posso estar enganado, mas o que eu entendi aí é que pode gerar efeito indefinido caso de um EOF. Talvez a execução do programa pare por conta disso levando a outros erros, mas talvez não. Nunca aconteceu comigo de o programa parar por causa dessa função. Talvez porquê eu usei elas nos lugares corretos. Tem razões para usar e para não usar. Como por exemplo, antes de um Scanf é legal usar, dentro do while. Já pra um redimencionamento para arquivo não é legal, como disse um user acima.
Espero que você tenha lido o que eu escrevi no primeiro post, isto é, o meu artigo sobre o assunto.
Você não entendeu o que está escrito na documentação.
fflush RETORNA EOF no caso de ERRO.
O efeito é INDEFINIDO no caso de streams de ENTRADA.
>
Mas só estou falando que na minha humilde opinião, não tem porque não usar a função em determinados casos.
Se o efeito é INDEFINIDO, logo, não sabemos o que vai acontecer!Não é correto utilizar fflush(stdin) NUNCA, como está escrito na documentação! (fantástico não? está tudo no manual!)
E, a função gets...
A gente não fica bravo quando utiliza-se essa função, ficamos FURIOSOS!
Afinal, a função é vulnerável...
Leia o segundo post deste tópico
Abraços
http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif
FACEPALM!
Bom tópico.
Deve ser a forma mais fácil de limpar o buffer
;)
Outro adendo, que não é sobre fflush(stdin) e nem system, mas pelo menos fica tudo num tópico só e deixa mais fácil indicar o link: tipo de retorno da função main.
Segundo o C99:
"The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters ( int main(void) ) or with to parameters (refered to here as argc and argv, though any names may be used, as they are local to the function in which they are declared)"
"The return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified."
Frisando: Se o tipo de retorno do main não for compatível com int, o status de retorno p/ o ambiente não é especificado. Agora, os códigos:
>
isis@linux-45c9:~/src> cat tmain.c
float main(void) {
return 123.48F;
}
isis@linux-45c9:~/src> gcc tmain.c
tmain.c: In function main:
tmain.c:1: warning: return type of main is not int
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
195
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
195
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
195
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
195
>
isis@linux-45c9:~/src> cat tmain2.c
struct p {
int a;
int b;
char* q;
};
struct p main(void) {
struct p ts = {2,3, "ps axu"};
return ts;
}
isis@linux-45c9:~/src> ./a.out
Falha de segmentação
isis@linux-45c9:~/src> echo $?
139
isis@linux-45c9:~/src> ./a.out
Falha de segmentação
isis@linux-45c9:~/src> echo $?
139
isis@linux-45c9:~/src> ./a.out
Falha de segmentação
isis@linux-45c9:~/src> echo $?
139
isis@linux-45c9:~/src> ./a.out
Falha de segmentação
isis@linux-45c9:~/src> echo $?
139
>
isis@linux-45c9:~/src> cat tmain3.c
char main() {
return 'a';
}
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
97
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
97
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
97
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
97
>
isis@linux-45c9:~/src> cat tmain4.c
char * main() {
return "123123";
}
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
192
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
192
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
192
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
192
>
isis@linux-45c9:~/src> cat tmain5.c
void main() {
}
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
148
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
132
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
148
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
228
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
116
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
148
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
100
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
164
>
isis@linux-45c9:~/src> cat tmain6.c
void main() {
return;
}
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
52
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
148
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
244
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
164
isis@linux-45c9:~/src> ./a.out
isis@linux-45c9:~/src> echo $?
20
A partir desses pequenos programas, nota-se que o void main sem o return ocasiona um valor de retorno aleatório ao sistema operacional. Por que isso acontece? Veja o próximo programa:
>
isis@linux-45c9:~/src> cat tmain7.c
int main() {
return 90;
}
isis@linux-45c9:~/src> cat tmain7.s
.file "tmain7.c"
.text
.globl main
.type main, @function
main:
leal 4(%esp), ìx
andl $-16, %esp
pushl -4(ìx)
pushl ëp
movl %esp, ëp
pushl ìx
movl $90, êx
popl ìx
popl ëp
leal -4(ìx), %esp
ret
.size main, .-main
.ident "GCC: (SUSE Linux) 4.3.2 [gcc-4_3-branch revision 141291]"
.section .comment.SUSE.OPTs,"MS",@progbits,1
.ascii "ospwg"
.section .note.GNU-stack,"",@progbits
Note que o valor passado para a função return é colocado no registrador $eax, utilizado para armazenar valores de retorno de funções. No código assembly do void main não temos a presença da instrução movl para o $eax, ou seja, qualquer valor que esteja lá (por término de algum outro processo no sistema ou através de somas, já que o $eax também serve de registrador acumulador), vai ser retornado.
>
isis@linux-45c9:~/src> cat tmain6.s
.file "tmain6.c"
.text
.globl main
.type main, @function
main:
leal 4(%esp), ìx
andl $-16, %esp
pushl -4(ìx)
pushl ëp
movl %esp, ëp
pushl ìx
popl ìx
popl ëp
leal -4(ìx), %esp
ret
.size main, .-main
.ident "GCC: (SUSE Linux) 4.3.2 [gcc-4_3-branch revision 141291]"
.section .comment.SUSE.OPTs,"MS",@progbits,1
.ascii "ospwg"
.section .note.GNU-stack,"",@progbits
>
isis@linux-45c9:~/src> gcc -S tmain5.c
tmain5.c: In function main:
tmain5.c:1: warning: return type of main is not int
isis@linux-45c9:~/src> cat tmain5.s
.file "tmain5.c"
.text
.globl main
.type main, @function
main:
leal 4(%esp), ìx
andl $-16, %esp
pushl -4(ìx)
pushl ëp
movl %esp, ëp
pushl ìx
popl ìx
popl ëp
leal -4(ìx), %esp
ret
.size main, .-main
.ident "GCC: (SUSE Linux) 4.3.2 [gcc-4_3-branch revision 141291]"
.section .comment.SUSE.OPTs,"MS",@progbits,1
.ascii "ospwg"
.section .note.GNU-stack,"",@progbits
>
Como contornar?Por que não devemos usar fflush(stdin) se ele "funciona" direito??
Na documentação da função está escrito: "effect undefined for input streams".
Se nem eles (que escreveram a função) sabem o que acontece, nós, simples mortais /applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/happy.gif&key=d39e68bd94edabd9069b8f4a6d941163110d4d36d12e6324ad75ec83de4843df" alt="happy.gif" />, muito menos!
Não é que não sabem o que acontece.
"effect undefined for input streams" Quer dizer que fflush pode ser diferente dependendo do sistema operacional. Ou seja, no windows ela pode limpar o buffer e mandar para o kernel, mas no linux pode apenas mandar o buffer para o kernel. Este é o problema dessa função em relação as outras.
Estou começando a aprende C, e aprendi usando "System("pause")" e "fflush(stdin)". Pra mim esse tópico foi de GRANDE utilidade, agradeço ^^
Eu estou tendo problemas com o buffer usando o delimitador de string. Veja no seguinte código:
#include <stdio.h>
int main()
{
char Test[99];
do
{
scanf(" %3s",Test);
printf("%s\n",Test);
} while( 1 );
}
Eu desejo coletar apenas 3 caracteres da string digitada, e está saindo como planejado, mas o resto da string que não foi coletada fica no buffer, ocasionando o problema que você já deve ter percebido. :upset:
Utilizando o fflush(stdin) resolve, mas estou abolindo essa função da minha vida, o que eu devo fazer? Se puder me ajudar agradeço muito.
Olá! Como estão? Sou novo no fórum.
Me apresento... Podem me chamar vango.
Achei bem interessante este tema, e também esta potente ferramenta que é o fórum.
Vou deixar uma forma há mais para que não tenham problemas com o buffer.
A solução que eu proponho não vi em nenhum outro post assim me perdoem se faço duplo post, não é minha intenção:
Se vamos ler 2 char seguidos ou um char e uma string ou vice-versa, com 2 scanfs seguidos, a solução do "%c%*c" não está nada mal. Uma forma há mais de obter o mesmo resultado é por um espaço andes do especificador %c antes de ler o segundo char no segundo scanf, ou %s se for uma string. Entendeu?
Deixo um exemplo:
char a;
char b;
printf("Entre uma letra: ");
scanf( "%c", &a );
printf("Entre uma letra: ");
scanf( " %c", &b ); // <---NOTE o ESPAÇO ANTES DO %c entre " e % ISSO evita ter que por %*c no scanf anterior, o que faz é IGNORAR A ULTIMA LETRA que é '\n' sempre =)
Fácil né?
Espero que sirva de algo, o para alguém, já que é uma forma pouco corrente de evitar que entre lixo no buffer.
scanf( " %c", &b ); teria o mesmo efeito que por o especificador %*c no scanf anterior scanf( **"%c%*c"**, &a );
Sorte! :thumbsup:
Para limpar o stdin recomendo o uso de uma das funções abaixo:
void limpa_linha() {
scanf("%*[^\n]");
scanf("%*c");
}
ou essa:
void fflush_stdin() {
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
}
O uso do comando **fflush(stdin);** não é nada recomendado para limpar o **stdin**, ou "buffer de entrada"
É inútil. você posta e mesmo assim tem uns trolhas que ensinam a programar usando isso.