I am a novice in C, (just started learning it), so please do not pay much attention to my ignorance.
To the question now. It regards the use of [^\n]
in scanf()
(following the example of my study book). Nevertheless it seems that it does not work at all.
Thank you in advance.
The following snippet, when compiled, prints nothing (if the user enters a string with white-spaces). Why?
#include <stdio.h>
int main(void) {
char str[100];
printf("Enter a string: ");
scanf("%[˄\n]", str);
printf("%s\n", str);
return 0;
}
Thus, e.g., if the user enters This is a text
it outputs nothing! On the other hand, without [^\n]
, it does print the string up to the first white-space.
The character you typed in the format string is not the ASCII caret symbol, it is a Unicode circumflex accent ˄
U+02C4 encoded in UTF-8 as the 2 bytes [CB 84]. The format string is hence %[\xCB\x84\n]
so scanf()
only accepts a sequence of any combination of these 3 bytes.
If the user inputs anything else as the first character, scanf()
will return 0
after the user hits the Enter key. Conversely, if the user hits the Enter key, the \n
is accepted and input continues until a character different from the 3 bytes is entered, but which will only be made available if the user hits the Enter key another time.
The observed behavior is the input continues as long as only the Enter key is typed and multiple newlines are then output, those in str
followed by a final newline.
You probably typed the circumflex accent on your keyboard (possibly a French AZERTY or similar layout) followed by a space instead of the AltGr9 key combination.
There are other problems with the %[^\n]
format:
scanf()
to find the length of the destination array, and any sufficiently long input will cause a buffer overflow. You should write %99[^\n]
.scanf()
will return 0
, leaving the buffer str
unchanged, hence uninitialized.scanf()
will return EOF
, also without modifying the buffer str
.scanf()
or fgets()
.Therefore you should always test the return value of scanf()
to detect and report invalid or missing input instead of invoking undefined behavior, and it is less confusing to use fgets()
to read strings from the user.
Here is a modified version:
#include <stdio.h>
int main(void) {
char str[100];
printf("Enter a string: ");
if (scanf("%99[^\n]", str) == 1) {
printf("%s\n", str);
} else {
printf("invalid or missing input\n");
}
return 0;
}
Here is a recommended approach to input a string from the user using fgets()
:
#include <stdio.h>
#include <string.h>
int main(void) {
char str[101];
printf("Enter a string: ");
if (fgets(str, sizeof str, stdin)) {
str[strcspn(str, "\n")] = '\0'; // strip the trailing newline if any
printf("%s\n", str);
} else {
printf("cannot read from input\n");
}
return 0;
}