Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

PJM

fgets

Recommended Posts

PJM

#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

Share this post


Link to post
Share on other sites
Knitter

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);

Share this post


Link to post
Share on other sites
pwseo

Pode sempre dizer ao scanf para descartar o \n.

Ex. (ler uma string até 50 char e descartar o \n no final)

scanf("%50s%*[\n]", cenas)

Share this post


Link to post
Share on other sites
Knitter

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.

Share this post


Link to post
Share on other sites
pwseo

Realmente, não sei o que me deu para meter aquele 50 ali. Estava a pensar num input de tamanho fixo, sorry

Share this post


Link to post
Share on other sites
Knitter

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 :D

Share this post


Link to post
Share on other sites
pwseo

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 ;)

Share this post


Link to post
Share on other sites
PJM

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 :D

Share this post


Link to post
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

×

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.