The format %(limit)[^\n] for scanf function is unsafe ? (where (limit) is the length -1 of the string)
If it is unsafe, why ?
And there is a safe way to implement a function that catch strings just using scanf() ?
On Linux Programmer's Manual, (typing man scanf on terminal), the s format said:
Matches a sequence of non-white-space characters; the next pointer must be a pointer to character array that is long enough to hold the input sequence and the terminating null byte ('\0'),which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first.
The input string stops at maximum field width always ? Or is just on GCC ?
Thanks.
%(limit)[^\n]for scanf" is usually safe.In the below example, at most 99
charwill be read and saved intobuf. If anycharare saved, a'\0'will be appended andcntwill be 1.This functionality is certainly safe, but what about others?
Problems occur when the input is a lone
"\n".In this case, nothing is saved in
bufand 0 is returned. Had the next line of code been the following, the output is Undefined Behavior asbufis not initialized to anything.A better following line would be
Problems because the
'\n'was not consumed.The
'\n'is still waiting to be read and another call toscanf("%99[^\n]", buf);will not read the'\n'.Q: is a safe way to implement a function that catch strings just using scanf()
A: Pedantically: Not easily.
scanf(),fgets(), etc. are best used for reading text, not strings. In C a string is an array ofcharterminated with a'\0'. Input viascanf(),fgets(), etc. typically have issues reading'\0'and typically thatcharis not in the input anyways. Usually input is thought of as groups ofcharterminated by'\n'or other white-space.If code is reading input terminated with
'\n', usingfgets()works well and is portable.fgets()too has it weakness that are handled in various ways .getline()is a nice alternative.A close approximate would be
scanf(" %99[^\n]", buf)(note the added" "), but alone that does not solve handing excessive long lines, reading multiple empty lines, embedded'\0'detection, loss of ability to report length read (strlen()does not work due to embedded'\0') and its leaving the trailing'\n' instdin.Short of using
scanf("%c", &ch)with lots of surrounding code (which is silly, just usefgetc()) , I see no way to use a singlescanf()absolutely safely when reading a line of user input.Q: The input string stops at maximum field width always ?
A: With
scanf("%99[^\n]", input stops 1) when a'\n'is encountered - the'\n'is not saved and remains in the file input buffer 2) 99charhave been read 3) EOF occurs or 4) IO error occurs (rare).