4

i have a problem with the use of fgets. The loop is supposed to read a line of max. 19 characters, analyze this char array and then wait for next input. The problem is that if the line entered exeeds 19 characters, fgets will fill str with the remaining characters untill Ctrl-D or newline is entered, thus initiating a new loop without new input. The input (stdin) should in some way be flushed after 19 characters are read, so the loop can start with a clean slate. Anyone have a solution to this?

 char str[20]; while((fgets(str, 20, stdin) != NULL)) { puts(str); //monitoring str if(str[0] == 'q') break; } 

Example in use:

hola hola //user inputs 9 chars + newline hola hola //puts writes hoo hoo hoo hoo hooh //user inputs 20 chars + newline hoo hoo hoo hoo hoo //puts writes h // 

5 Answers 5

6

scanf("%*[^\n]\n"); is probably one of the simplest possibilities.

Sign up to request clarification or add additional context in comments.

7 Comments

I suppose you must pass a char buffer argument. This solution does not check for buffer overflow, does it? Gosh my C is so rusty.
@xpmatteo : it does not need a buffer argument. From man scanf: "An optional '*' assignment-suppression character: scanf() reads input as directed by the conversion specification, but discards the input. No corresponding pointer argument is required"
As @Giuseppe pointed out, part of the beauty of this is that you don't have to pass a buffer. Since there's no buffer, there's no possibility of buffer overflow either. Don't blame yourself for not recognizing this though: this conversion is definitely on the esoteric side.
You do need to check if the string that fgets() read finished with a \n first, otherwise you'll read and discard the next line.
You probably want to use "%*[^\n]%*c" instead of "%*[^\n]\n". The \n does not match a literal newline but instead discards any amount of whitespace up to the next non-whitespace character.
|
2
char str[21]; /* read one extra character */ while (fgets(str, 21, stdin) != NULL) { /* if line too long, truncate and swallow the rest of the line */ if (strlen(str) > 19) { str[19] = '\0'; while (getchar() != '\n' && !feof(stdin)) ; } puts(str); if(str[0] == 'q') break; } 

Comments

0

Another possible variant with constraint of fgets() being the only input used and at loop level. It's definitely very similar to what larsman proposed. So I suppose I will vote for him :-)

#include <stdio.h> int main(){ char str[20]; int skip = 0; str[19] = 1; while (fgets(str, 20, stdin)) { // just ignore lines of more than 19 chars if (str[19] == 0){ str[19] = 1; skip = 1; continue; } // also skip the end of long lines if (skip) { skip = 0; continue; } // monitor input puts(str); // stop on any line beginning with 'q' if (str[0] == 'q'){ break; } }; } 

Comments

0

Have a look at fpurge:

fpurge(stdin); 

Comments

-2

Try:

fgets(str, 2000, stdin) 

Then truncate str to 19 :-)

2 Comments

...and hope the user never pastes in a line that's 2 MB long!
True :-) but it's a quick solution.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.