I could not find the answer anywhere else.
%[^\n]
- When I run this one, scanf
is getting input and terminating after I press enter. ( Probably leaving \n
in the input system)
%[^\n]\n
- this one is getting the input but scanf
is NOT terminating immediately after I press enter like the one above. I hit more enter and it makes more newlines. When I give a character and then press enter it finally terminates. Example:
int main(void)
{
char s[100];
scanf("%[^\n]\n", s);
printf("%s", s);
return 0;
}
The results:
Last one:
%[^\n]%*c
- When I give some input and press enter. scanf
immediately terminates.
How do those 3 work and how do they differ?
^\n stands for taking input until a newline isn't encountered. Then, with this %*c, it reads the newline character and here, the used * indicates that this newline character is discarded. Follow this answer to receive notifications.
So scanf("%[^\n]", s); will read all characters until you reach \n (or EOF ) and put them in s . It is a common idiom to read a whole line in C.
In short, the statement. scanf(“%[^\n]%*c”,name); means that all the characters entered as the input, including the spaces, until we hit the enter button are stored in the variable, name; provided we allocate sufficient memory for the variable.
%[^\n] is for reading string until hit to \n or EOF. Whitespaces can be included in the string. %s is for reading string until hit to whitespace or EOF.
All 3 format begin with "%[^\n]"
.
"%[^\n]"
is poor code2 that lacks a width limit and is susceptible to buffer overrun. Use a width limit like "%99[^\n]"
with char s[100];
.
"%[...]"
does not consume leading whitespace like many other specifiers.
This specifier directs reading input until a '\n'
1 is encountered. The '\n'
is put back into stdin
. All other characters are saved in the matching destination's array s
.
If no characters were read (not counting the '\n'
), the specifier fails and scanf()
returns without changing s
- rest of the format is not used. No null character appended.
If characters were read, they are saved and a null character is appended to s
and scanning continues with the next portion of the format.
"\n"
acts just like " "
, "\t"
, "any_white_space_chracter"
and reads and tosses 0 or more whitespace characters. It continues to do so until a non-white-space1 is read. That non-whitespace character is put back into stdin
.
Given line buffered input, this means a line with non-whitespace following input is needed to see the next non-whitespace and allow scanf()
to move on.
With scanf()
, a "\n"
at the end of a format is bad and caused OP's problem.
"%*c"
reads 1 character1 and throws it away - even if it is not a '\n'
. This specifier does not contribute to the return count due to the '*'
.
A better alternative is to use fgets()
.
char s[100];
if (fgets(s, sizeof s, stdin)) {
s[strcspn(s, "\n")] = '\0'; // To lop off potential trailing \n
A lesser alternative is
char s[100] = { 0 };
scanf("%99[^\n]", s);
// With a separate scanf ....
scanf("%*1[\n]"); // read the next character if it is a \n and toss it.
1 ... or end-of-file or rare input error.
2 IMO, worse than gets()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With