What is the behavior of% (limit) [^ \ n] in scanf? Is it overflow safety?

Function %(limit)[^\n]

for scanf

unsafe? (where (limit) is -1 line length)

If it's not safe, why?

And is there a safe way to implement a function that only catches strings with scanf ()?

In the Linux Programming Guide (by typing man scanf on a terminal), the format s

said:

Matches a sequence of non-white space characters; the next pointer must be a pointer to a character array long enough to hold the input sequence and a terminating null byte ('\ 0') that is added automatically. The input line stops at white space or at the maximum field width, whichever comes first.

Does the input string always stop at the maximum field width? Or just GCC?

Thank.

+3


source to share


2 answers


%(limit)[^\n]

for scanf "is usually safe.

In the example below, at most 99 char

will be read and stored in buf

. If saved char

, will be added '\0'

and cnt

will be 1.

char buf[100];
int cnt = scanf("%99[^\n]", buf);

      

This functionality is certainly safe, but what about others?


Problems arise when the input is single "\n"

.

In this case, nothing is stored in buf

and 0 is returned. If the next line of code was next, the output is Undefined. Behavior as is buf

not initialized by anything.

puts(buf);

      

The best next line would be

if (cnt == 1) puts(buf);
else printf("Return count = %d\n", cnt);

      



Problems because '\n'

it was not used.

'\n'

is still waiting to be read and another call scanf("%99[^\n]", buf);

will not read '\n'

.


Q: this is a safe way to implement a function that only catches strings with scanf ()
A: Pedantic: not easy.

scanf()

, fgets()

etc. best used for reading text, not strings. In C, a string is an array char

terminated with '\0'

. Login through scanf()

, fgets()

etc. Usually has problems with reading '\0'

and, as a rule, char

does not enter the input in any way. Typically, an input is considered a group char

terminated '\n'

or some other white space.

If the code input is read with '\n'

, the usage fgets()

works well and is portable. fgets()

also has a weakness that is handled in various ways. getline()

is a good alternative.

The closest approximate would be scanf(" %99[^\n]", buf)

(note the added one " "

), but one that doesn't solve the transmission of excessive long lines, reading multiple blank lines, inline detection '\0'

, losing the ability to report read length ( strlen()

doesn't work because of the inline '\0'

) and it leaves the trailing '\n

'in stdin

...

Except for use scanf("%c", &ch)

with a lot of surrounding code (which is silly, just use fgetc()

), I don't see an absolutely safe use of one scanf()

when reading a user's input line.


Q: does the input line always stop at the maximum field width?
A: When the scanf("%99[^\n]"

input stops 1) when it '\n'

is encountered it is '\n'

not saved and remains in the file input buffer 2) 99 char

was read 3) EOF occurs or 4) IO error occurs (rarely).

+3


source


[^ \ n] must make scanf read input until it encounters a new line character ... while the limit is the maximum number of characters scanf must read ...



+1


source







All Articles