Continuing from my comment, until you thoroughly understand the pitfalls of scanf(), it is recommended you use fgets() for all user and file input so that you consume a complete line of input with each read. That way what remains in the input stream does not depend on the conversion specifier used and whether a matching-failure occurs. If you then need to extract information from the line read by fgets() you can use sscanf() and regardless of whether sscanf() succeeds or fails, it does not impact what is left in your input stream unread.
All line-oriented input functions, fgets() and POSIX getline() read and include the '\n' as part of the buffer they fill. You simply trim the '\n' from the end of the stored line after your call to fgets() using strcspn() to determine the number of characters before the '\n' and then overwrite the '\n' with the nul-terminating character '\0' (which is simply ASCII 0).
You handle user-input or lines read from a file the exact same way. For example, you can prompt the user for a filename, read the input, open the file, and then read all lines in the file as follows:
#include <stdio.h>
#include <string.h>
#define MAXC 1024 /* if you need a constant, #define on (or more) */
int main (void) {
char fname[MAXC], line[MAXC]; /* storage for filename & line */
FILE *fp = NULL; /* FILE pointer */
fputs ("enter filename: ", stdout); /* prompt */
if (!fgets (fname, MAXC, stdin) || *fname == '\n') { /* check EOF or empty line */
puts ("(user canceled input)");
return 1;
}
fname[strcspn (fname, "\n")] = 0; /* trim \n from end */
if (!(fp = fopen (fname, "r"))) { /* validate file open succeeds */
perror ("fopen-fname"); /* fopen sets errno on failure */
return 1;
}
putchar ('\n'); /* provide space before output */
while (fgets (line, MAXC, fp)) { /* read each line from file */
line[strcspn (line, "\n")] = 0; /* trim \n from end */
puts (line); /* output line */
}
fclose (fp); /* close file when done */
}
Note, when taking any type of input, every single step must be validated. Otherwise, if you fail to validate, and an input fails, you will invoke undefined behavior if you blindly use the variable containing an indeterminate value.
Example Use/Output
$ ./bin/readfile
enter filename: dat/fleas.txt
My dog has fleas
My cat has none
Lucky cat
fgets() provides one of the most robust ways to handle input. You can use scanf() as well -- so long as you understand each pitfall associated with its use and you protect against it. Let me know if you have further questions.
"%s"as a conversion specifier in scanf. Doing so is just as bad as usinggets.if( inFile == NULL ) { perror(fileName); exit(EXIT_FAILURE);}scanf()at all, until you understand the pitfalls thoroughly enough to know why it shouldn't be used. Declare a sufficiently size array, e.g.char line[1024];and read into lineif (fgets (line, sizeof line, stdin) == NULL) { /* handle EOF */ }now simply trim the'\n'from the end of line withline[strcspn (line, "\n")] = 0;-- done.