I'm reading a string from sdin with a scanf by doing:
scanf("%[^\n]s", msg);
%[^\n]s
reads till a new line character is found. Is this legal in ANSI-C?
You should not use this format for multiple reasons:
The s
in "%[^\n]s"
is not part of the conversion specifier, it is a plain character that scanf
will try to match after the characters read from the line, at a time where the current character is either a newline or the end of file. You should remove the s
.
scanf("%[^\n]", msg);
will fail and return 0, leaving msg
unchanged if the user hits enter with an empty input line.
scanf("%[^\n]", msg);
will cause a buffer overflow for any sufficiently long input line. The maximum number of characters to store into the array pointed to by msg
should be specified between the %
and the [
as:
char buf[100];
if (scanf("%99[^\n]", msg) == 1) {
// msg contains the input line, up to 99 characters
// the remainder if this input line is still in stdin
// so is the newline
}
scanf("%99[^\n]", msg);
does not consume the newline and leaves extra characters in the input stream if more than 99 were typed before the newline, which may of may not be the expected behavior.
Here is a safer alternative:
// read a line of input, discard extra characters and the trailing newline
int mygets(char *dest, size_t size) {
int c;
size_t i = 0;
while ((c = getchar()) != EOF && c != '\n') {
if (i + 1 < size) {
dest[i++] = c;
}
}
if (size > 0)
dest[i] = '\0';
if (c == EOF && (i == 0 || ferror(stdin)))
return EOF;
else
return (int)i;
}