Jump to content

fgets


PJM
 Share

Recommended Posts

#include <stdio.h>

int main()
{
char cenas[255];
int a;

while (1)
{
	printf("Nome:");fgets(cenas,255,stdin);
	if (cenas[0] == '\n') break;
	printf("Num:");scanf("%d\n", &a);
};

return 0;
}

Alguém sabe porque é que isto não funciona bem?

O que eu queria fazer era inserir um texto e depois um numero n vezes, pois não sei quantos elementos irei inserir.

(Isto é um código de teste para depois implementar no trabalho)

Basicamente o input tanto pode ser:

Evento1

15

Evento2

16

Como:

Evento15

90

Evento16

50

Evento17

95

basicamente a única forma de delimitar o nr de eventos seria ao ler o nome e verificar se este tinha uma quebra de linha acho

Link to comment
Share on other sites

Nunca mistures métodos de leitura diferentes, scanf e fgets não se dão bem, ou usas sempre scanf (desaconselhado) ou usas sempre fgets e depois eventualmente outras funções para tratar os dados.

Isso não funciona por uma razão simples, o primeiro fgets lê dados do stdin, o primeiro scanf lê o número e deixa lá o '\n', mesmo que coloques o \n no texto não estás a dizer para o scanf o ler, na verdade está a ficar no buffer. O segundo fgets quando for ler já lá tem um \n pendurado, e nem precisa que o utilizador introduza dados porque o '\n' que lá está é suficiente para ser considerado dados a ler.

Se quiseres usar mesmo o scanf, depois de cada leitura terás de fazer algo do género de:

char ch;
while ((ch = getchar()) != '\n' && ch != EOF);

E podes limitar o número de caracteres lidos desta forma

scanf("%255s", cenas);
Link to comment
Share on other sites

Isso na verdade não descarta os valores, se o utilizador introduzir mais de 50 caracteres continua a existir dados dentro do buffer e pior, estás a indicar que o scanf tem de ler até 50 caracteres seguidos de um \n, que se não for o caso resulta num valor vazio para a leitura porque o scanf não lê se encontrar um falha de leitura.

De qualquer forma, é sempre possível acrescentar mais protecções e limitações mas mesmo isso não impede todos os problemas do scanf, o melhor mesmo é deixar de usar o scanf e usar apenas o fgets. É o recomendado e é o que dá menos problemas, quer com buffers, quer com limitação de dados. Para input do utilizador o scanf é simplesmente mau.

Já agora deixo um óptimo recurso, http://c-faq.com/questions.html especialmente a secção 12, sobre leitura de dados, e a pergunta 12.20 http://c-faq.com/stdio/scanfprobs.html que inclui duas explicações longas sobre o uso e o problema dos scanfs.

Link to comment
Share on other sites

Repara que até é uma solução, no entanto abre mais problemas. Por isso é que não gosto de usar muito o scanf ou então, se usar o scanf só uso essa função e depois de cada um uso o truque para limpar os dados do buffer. Mas acho que cada solução que surge com o scanf abre mais um conjunto de problemas 😄

Link to comment
Share on other sites

Não, não é solução nenhuma porque o input era variável e eu estava a dizer que além dos 50 chars queria o '\n' xD

Foi mesmo uma boa oportunidade de não ter dito nada lool. De qualquer modo, também gosto mais de fgets e só dps sscanf 😉

Link to comment
Share on other sites

A sério? O scanf é má politica?

Ainda estou a aprender, no entanto não testei essa solução mas resolvi o problema com:

while (!feof(stdin)) AddEvent( etc...)

e funciona, pois enquanto não chegar ao fim do stdin ele continua adicionando dados

Obrigado pela explicação 😄

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.