Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fgets doesn't wait for the keyboard input

Tags:

c

I want to read two strings from ther user's keyboard input, this is the code I tried :

char nomFichier[50], emp[100], empEtNomFichier[150];
printf("\nDonner le nom du fichier : ");
fgets(nomFichier, sizeof nomFichier, stdin);
printf("\nDonner l'emplacement du fichier : ");
fgets(emp, sizeof emp, stdin)
sprintf(empEtNomFichier, "%s/%s", emp, nomFichier);

The problem is when I run this code, the program doesn't wait for the keyboard input for the first fgets(), ad this is how the program looks :

Donner le nom du fichier : 
Donner l'emplacement du fichier : /home/ee/Desktop
/home/ee/Desktop
like image 212
Croviajo Avatar asked Mar 23 '23 06:03

Croviajo


1 Answers

The problem is really that fgets() reads the terminating newline into the string. Unless the buffer fills up, or EOF is encountered without a newline, the last character in the returned string will be '\n'.

Get rid of that by:

n = strlen(nomFichier);
if (n>0 && nomFichier[n-1]=='\n') { nomFichier[n-1] = 0; }

...and do the same for the emp string inside the if block. There are also ways to use strtok with '\n' as a delimiter, or use sscanf with a "%xx[^\n]%*c" format, plus I'm sure others have different favorite solutions. ("xx" is the maximum string length, in decimal, in that scanf format.)

By the way, the other problem can't be portably addressed by fflush because fflush doesn't necessarily do anything. GNU C implementations, for example, treat fflush(stdin) as a no-operation.

The problem is most likely due to a prior scanf() that read a value, but didn't read the newline. Programs that switch between token-oriented input (scanf/fscanf) and line-oriented input (fgets) must be prepared to deal with the leftover line.

The quickest fix is:

scanf("%*[^\n]%*c"); /* discard up to and including the next '\n' character */

...or the more direct:

int c;
while ( (c = getchar()) != EOF && c != '\n') { }

Either way, I'd put that in a static function and let the optimizer decide whether to inline it or not.

You need to do that each time you switch from scanf() to fgets() input.

like image 143
Mike Housky Avatar answered Apr 02 '23 20:04

Mike Housky