Fgets does not work after scanf

#include <stdio.h> #include <string.h> #include <ctype.h> void delspace(char *str); int main() { int i, loops; char s1[101], s2[101]; scanf("%d", &loops); while (loops--) { fgets(s1, 101, stdin); fgets(s2, 101, stdin); s1[strlen(s1)] = '\0'; s2[strlen(s2)] = '\0'; if (s1[0] == '\n' && s2[0] == '\n') { printf("YES\n"); continue; } delspace(s1); delspace(s2); for (i = 0; s1[i] != '\0'; i++) s1[i] = tolower(s1[i]); for (i = 0; s2[i] != '\0'; i++) s2[i] = tolower(s2[i]); if (strcmp(s1, s2) == 0) { printf("YES\n"); } else { printf("NO\n"); } } return 0; } void delspace(char* str) { int i = 0; int j = 0; char sTmp[strlen(str)]; while (str[i++] != '\0') { if (str[i] != ' ') { sTmp[j++] = str[i]; } } sTmp[j] = '\0'; strcpy(str, sTmp); } 

After entering "loops" "s1", an empty string is automatically assigned. How does this happen? I am sure my keyboard is working fine.

+9
source share
7 answers

scanf() reads exactly what you requested, leaving the next \n from the end of this line in the buffer where fgets() will read it. Either do something to use a new line or (my preferred solution) fgets() and then sscanf() from that line.

+18
source

scanf leaves a space in the input buffer, including newlines. To use fgets to read the next line, you need to manually delete the rest of the current line:

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

Vine

Geekoaur answered your question well, I just point out another โ€œproblemโ€ with your code.

String s1[strlen(s1)] = '\0'; is no-op if s1 already completely zero termination before it is executed.

But if s1 NOT all true zero termination before this line is executed (and you're out of luck), this will result in:

  • a SIGSEGV on a POSIX system (* nix).
  • a GPF on Windows.

This is because strlen basicaly finds the index of an existing null terminator and returns it! Here's a valid, non-optimized strlen implementation:

 int strlen(char *string) { int i = 0; while(string[i] != '\0') { ++i; } return i; } 

So ... If you REALLY worry that the lines were NOT terminated by zeros, you would do something like:

  • string[sizeof(string)]='\0'; in local automatic strings (where the compiler โ€œknowsโ€ the size of the string);
  • or string[SIZE_OF_STRING] for all other strings, where SIZE_OF_STRING (usually) a #define 'd constant or variable that you support specifically to store the current SIZE (not length) dynamically allocated string.

And if you REALLY, REALLY, REALLY worried that the lines did not end in zero (for example, you deal with dirty methods libary (for example, Tuxedo ATMI), you ALSO clear "your" return lines "before passing them to methods suspicious library using:

  • before: memset(string, NULL, SIZE_OF_STRING);
  • invoke: DirtyFunction(/*out*/string) ;
  • after: string[SIZE_OF_STRING]='\0'

SIG11 is a complete search binding because (if you didnโ€™t โ€œhookโ€ them with the signal processor and didnโ€™t say otherwise, they cause unix to hard-end your program, so you cannot register anything (after the fact) to help find out where-in-a-a-a-o-o-o-o-o-o ... especially considering that in many cases the line of code that throws SIG11 is not next to the actual reason that the line loses the zero delimiter .

Does that make sense to you?

Greeting. Whale.

PS: WARNING: strncpy IS NOT ALL IMPOSSIBLE ... you probably meant strlcpy . I learned this hard way ... when billing for $ 60 million worked.


EDIT:

FYI: Here is the "safe" (non-optimized) version of strlen, which I will call strnlen (I believe it should be in stdlib. Sigh.).

 // retuns the length of the string (capped at size-1) int strnlen(char *string, int size) { int i = 0; while( i<size && string[i]!='\0' ) { ++i; } return i; } 
+2
source

I know this is very old. I am new to c and want to test my method that uses getchar :

 #include <stdio.h> int main() { printf("Please enter your name\n"); char string[10]; scanf("%s", string); printf("Hello %s\n", string); //getchar(); # un commenting this line, fgets perfectly works!! printf("Please enter your name again\n"); fgets ( string, 10, stdin ); printf("Hello again %s", string); getchar(); } 
+1
source

just put scanf("%d\n",&loops);

instead of scanf("%d",&loops);

+1
source

The following works if fgets() "skipped" after using scanf()

By talking:

 scanf("%d", &loops); 

Say:

 char garbage[100]; fgets(garbage,100,stdin); 

This will save everything left on the input buffer in the garbage variable.

This will effectively clear the input buffer and allow you to use fgets() later.

EDIT: I recently found out that there is an easier solution than the above. If you say getchar () after scanf (), this will allow you to use fgets () without any problems. getchar () will receive the next character in the input buffer, which in this case will be "\ n". After removing '\ n' from the input buffer, fgets should work fine.

0
source

I solved your problem as follows. Now your program is working fine. If you have any doubts, you can ask me.

  #include<stdio.h> #include <string.h> int main() { int i, age; char phone[10]; char name[100]; printf("ENTER YOUR NAME:"); fgets(name , 100 , stdin); printf("ENTER YOUR AGE:"); scanf("%d",&age); printf("ENTER YOUR PHONE NUMBER:"); scanf(" "); fgets(phone,10,stdin); printf("\nStudent detail\n"); printf("Name: "); fputs(name , stdout ); printf("Age: %d\n",age); printf("Phone Number: "); puts(phone); printf("----\n"); return 0; } 
-one
source

All Articles