What does n mean in `sscanf (s,"% d% n ", & i, & n)`?

The user page indicates that the signature is sscanf

 sscanf(const char *restrict s, const char *restrict format, ...); 

I saw the answer in SO , where is the function in which sscanf used to check if the input is integer.

 bool is_int(char const* s) { int n; int i; return sscanf(s, "%d %n", &i, &n) == 1 && !s[n]; } 

Looking at !s[n] , it looks like we are checking to see if sscanf checks the sequence of characters before the ending character \0 . Therefore, I assume that n denotes the index, where sscanf will be on line s when the function ends.

But what about the variable i ? What does it mean?

Edit:

To be more explicit: I see that the sscanf signature requires a char * pointer as the first parameter. The format specifier is a seconf parameter, so that it knows how to parse a sequence of characters and as many variables as conversion specifiers as the following parameters. Now I understand that i designed to store a parsed integer.

Since there is only one format specifier, I tried to deduce the function n .

Is my assumption correct for n ?

+6
source share
4 answers

It seems that op already has his answer, but since I bothered to look at it myself and run the code ...

From section β€œC Pocket Link” (2nd edition by Herbert Shildt) scanf ():

% n Gets an integer equal to the number of characters read

and for the return value:

The scanf () function returns a number equal to the number of field numbers that were successfully assigned to the values

The sscanf () function works the same way, it just takes it from the argument of the provided buffer (s in this case). The test "== 1" ensures that only one integer has been parsed, and! S [n] ensures that the input buffer will be well completed after parsing the integer and / or that there really is only one integer in the chain.

By running this code, an s value like "32" gives a "true" value (we don’t have a bool defined as a type in our system), but s like "3 2" gives a value of "false" because s [n] in this case is "2", and n has the value 2 ("3" is parsed to create an int in this case). If s is "3", this function will still return true since everything that is filled with white space and n has a value of 3.

Another example of entering "3m" gives a "false" value, as you expected.

+7
source

Verbatim from sscanf() man page:

Conversions

[...]

n

Nothing is expected; instead, the number of characters consumed so far from the input is stored through the next pointer, which should be a pointer to an int. This is not a conversion, although it can be suppressed by the * assignment symbol. The standard reads: β€œThe implementation of the Directive% n does not increase the account assignment account returned at completion but the correction seems to contradict this. It is probably not wise to make any assumptions about the effect of% n conversions on the return value.

+2
source

variable i means until it reads the integer value vaalue.

what are you trying to ask? This is not too clear! the code will try to read an integer from the string in 'i'

0
source

I would like to indicate that the source code of the buggy is:

 bool is_int(char const* s) { int n; int i; return sscanf(s, "%d %n", &i, &n) == 1 && !s[n]; } 

I will explain why. And I will interpret the sscanf format string.

Firstly, buggy:

Given input "1", which is an integer, sscanf will store 1 in i. Then, since there is no space after the space, sscanf will not touch n. And n is not initialized. Since sscanf sets me to 1, the value returned by sscanf will be 1, which means 1 scanned field. Since sscanf returns 1, part of the expression

 sscanf(s, "%d %n", &i, &n) == 1 

will be true. Therefore, the other part of the && expression will be executed. And s [n] will gain access to some random place in memory, because n is not initialized.

Interpretation of the format:

 "%d %n" 

Trying to scan a number, which can be a decimal or an integer or a scientific notation number. A number is an integer followed by at least one space. Empty space would be space, \ n, \ t and some other non-printable characters. Only if followed by a space will it set n to the number of characters scanned to this point, including a space.

This code may be what is intended:

  static bool is_int(char const* s) { int i; int fld; return (fld = sscanf(s, "%i", &i)) == 1; } int main(int argc, char * argv[]) { bool ans = false; ans = is_int("1"); ans = is_int("m"); return 0; } 

This code is based on, if s is an integer, then sscanf will scan it, and fld will be exactly one. If s is not an integer, then fld will be zero or -1. Zero, if there is something else, like a word; and -1 if there is nothing but an empty string.

0
source

All Articles