Dúvida em C

S7sRuss

What is folding?
Estou a fazer um programa simples em C que pede-nos o nosso sexo e estado civil.
Há uma parte do código que é a seguinte:
puts("Qual o seu sexo: "); scanf("%c",&sexo);
puts("Qual o seu estado civil: "); scanf(" %c",&est_civil);

O problema é que quando respondemos á primeira pergunta fica guardado na memória mais de 3 letras. Ex: masculino, feminino. Logo o primeiro scanf detecta o m ou o f e o segundo scanf detecta o a ou o e.
Mas pretendo que o primeiro scanf registe a primeira letra da primeira pergunta e o segundo scanf registe a primeira letra da segunda pergunta.
Ex:
Qual o seu sexo: Masculino (o 1º scanf tem de registar M)
Qual o seu estado civil: Solteiro (o 2º scanf tem de registar S)
 
assumindo que confirmas cada palavra com um <Enter>, isto deve resolver o problema

Código:
puts(...);
scanf(...);
while(getchar()!='\n');
puts(...);
scanf(...);
while(getchar()!='\n');
 
Bem eu faria como o warrior disse:

char sexo[20],est_civil[20];
puts(
"Qual o seu sexo: ");
scanf(
"%s",sexo);
puts(
"Qual o seu estado civil: ");
scanf(
" %s",est_civil);
printf(
"O resultado e:%c %c\n",sexo[0],est_civil[0]);

Mas existem várias formas de o fazer :) ..
 
Já deu =)

Obrigado Rui Carlos. :)
O while(getchar()!='\n'); resolveu o problema.
Podes me explicar como funciona essa instrução?

Aqui fica o código que escrevi:
#include <stdio.h>
main()
{
char est_civil, sexo;
puts("Qual o seu sexo: "); scanf("%c",&sexo); while(getchar()!='\n');
if(sexo=='m'||sexo=='M')
sexo='o';
else
sexo='a';
puts("Qual o seu estado civil: "); scanf("%c",&est_civil); while(getchar()!='\n');
if (est_civil=='S'||est_civil=='s')
printf("Solteir");
else
if(est_civil=='C'||est_civil=='c')
printf("Casad");
else
if(est_civil=='D'||est_civil=='d')
printf("Divorciad");
else
if(est_civil=='V'||est_civil=='v')
printf("Viúv");
else
printf("Estado Civil Inv lido\n");
printf("%c\n",sexo);
}
 
Desculpem lá intervir e sem ofensa às partes interessadas mas a solução do Rui Carlos é de longe a mais "sapateira", a solução mais pitoresca no mínimo.

Contudo, se ainda assim queres ser teimoso e não usar a solução do Warrior, pelo menos faz:
Código:
puts(...);
scanf(...);
fflush(stdin);
puts(...);
scanf(...);
fflush(stdin);

Resolver isto com um While devia ser crime :P
 
Desculpem lá intervir e sem ofensa às partes interessadas mas a solução do Rui Carlos é de longe a mais "sapateira", a solução mais pitoresca no mínimo.

Contudo, se ainda assim queres ser teimoso e não usar a solução do Warrior, pelo menos faz:
Código:
puts(...);
scanf(...);
fflush(stdin);
puts(...);
scanf(...);
fflush(stdin);

Resolver isto com um While devia ser crime :P

e ficas à espera que o 'fflush(stdin);' te limpe o buffer de entrada... o problema é se ele não fizer isso!!! estás-te a esquecer que em ANSI C, a função 'fflush' é suposto ser aplicada a buffer abertos para escrita, sendo o efeito em buffers abertos para leitura (como é o caso do 'stdin') indefinido!!

dependendo do SO que estás a usar, pode ser que tenhas disponível a função 'fpurge', essa sim limpa buffer de entrada (mas não é ANSI).

por isso parece-me que é mais crime resolver isto com um 'fflush' do que com um 'while' (já agora, podes-me dizer qual é o crime de resolver isto com um 'while'? e estar a criar variáveis para ler lixo também não é crime? por que não ignorá-lo simplesmente? acho a solução do Warrior perfeitamente válida, mas não seria a que eu utilizaria).

-----------

já me esquecia de explicar a instrução...

o while(getchar()!='\n'); executa a função getchar até que esta leia um '\n', ou seja, lê todos os caracteres até encontrar o primeiro '\n' (inclusivé). se tinhas no buffer os caracteres "asculino\n" eles serão todos lidos.
 
Última edição:
Pois, enfim ... devo ser muito estúpido então por preferir a minha solução que funciona e para uma string com uma infinidade caracteres é simplesmente muito mais efectiva que solução do while (que vai percorrer a string toda até achar o \n [só a ideia da carga que isto é para strings grandes dá-me arrepios]).

Big deal, não é ANSI C e os resultados são "indefinidos" ... pois claro, tem graça que sempre que a usei (em Windows e Linux com o Borland C++ Builder e gcc) funcionou sempre às mil maravilhas como era esperado.

Mas enfim, leva lá a bicicleta. Deixa-me lá ficar estúpido com as minhas soluções de programação que nem funcionam e fica lá tu com as tuas ;)
 
se fize-se o programa também usaria o fflush(stdin) .... por acaso n sabia que o fflush() era apenas usado para limpar o buffer abertos para escrita .... :)...

A mim até agora nunca me deu problemas a usar em buffer abertos para leitura....

Existe alguma função mesmo propria de ANSI C para limpar o buffer aberto para leitura?
 
é curioso que o nunca vi o fflush a funcionar (tanto em Linux como em MacOSX), devo ser muito estúpido para isto acontecer...

7.19.5.2 The fflush function
Synopsis
#include <stdio.h>
int fflush(FILE *stream);

Description
If stream points to an output stream or an update stream in which the most recent
operation was not input, the fflush function causes any unwritten data for that stream
to be delivered to the host environment to be written to the file; otherwise, the behavior is
undefined.
If streamis a null pointer, the fflush function performs this flushing action on all
streams for which the behavior is defined above.

Returns
The fflush function sets the error indicator for the stream and returns EOF if a write
error occurs, otherwise it returns zero.
 
Mas tens melhor ainda, se o facto de não ser ANSI C te faz tanta comichão e já que sabes tanto de programação, podes sempre arranjar uma solução para limpar o buffer de entrada que não implique percorrer a string toda.

Tem de haver alguma forma...
 
é curioso que o nunca vi o fflush a funcionar (tanto em Linux como em MacOSX), devo ser muito estúpido para isto acontecer...

Por acaso só programo em windows, por emquanto... e nunca me deu problemas ... foi só por isso que referi :D ...

Mas tem de haver alguma função para n termos de correr a string toda como o _freelancer_ tá a dizer...
 
Mas tens melhor ainda, se o facto de não ser ANSI C te faz tanta comichão e já que sabes tanto de programação, podes sempre arranjar uma solução para limpar o buffer de entrada que não implique percorrer a string toda.

Tem de haver alguma forma...

se não fosse ANSI mas estivesse dentro de outro standard que me garantisse que ela funcionaria, não tinha problemas em usá-la.

mas pelo que tenho lido lido na net, essa função só limpa o stdin em Windows (e como só programo em C para ambientes Unix, tenho que arranjar outra forma de resolver o problema).
 
Todas as sugestões que me deram funcionam em Windows.
Podem me explicar como funciona o fflush(stdin) e o rewind(stdin)?

Como deves saber sempre que é executado um programa em C são abertos 5 ficheiros standart...

stdin -> normalmente associado ao teclado
stdout -> normalmente associado ao monitor
stderr -> para onde deves mandar as mensagens de erro...
...
...

quando fazes fflush(stdin) supostamente tás a limpar o que está no buffer do stdin ... ficando assim vazio....

rewind(stdin) mete o apontador do stdin a apontar para o começo do buffer....

provavelmente devo-te estár a enganar em alguns detalhes.... por isso espera que alguém confirme....
 
Não seria mais facil fazer isto no 2º scanf, scanf(" %c",&est_civil),ou seja meter um espaço no " %c" de forma a limpar-mos o buffer do teclado.
O getchar que falaram faz exactamente a mm coisa quando utilizado associado ao \n,ou seja limpa o buffer..

Obrigado
Cumps
 
Última edição:
Não seria mais facil fazer isto no 2º scanf, scanf(" %c",&est_civil),ou seja meter um espaço no " %c" de forma a limpar-mos o buffer do teclado.
O getchar que falaram faz exactamente a mm coisa quando utilizado associado ao \n,ou seja limpa o buffer..

Obrigado
Cumps

épa eu por acaso nem me lembrei disso .... a primeira vez que precisei de limpar o buffer fiz assim.... depois habituei-me ao fflush(stdin) que pelo que houvi nem se deve usar....
 
Back
Topo