Scanf (), field width, inf and nan

In standard C since 1999 scanf()and strtod()should accept infinity and NaN as inputs (if they are supported by the implementation).

The description of both functions has a peculiar language that can be open to interpretation.

scanf():

An input element is defined as the longest sequence of input characters that does not exceed a given field width and is or is a prefix corresponding to the input sequence.

strtod():

The subject’s sequence is defined as the longest initial subsequence of the input string, starting with the first character of a non-white space, that is, the expected shape.

While the last excerpt seems to be strict, requiring specific forms of "INF", "INFINITY", "NAN" or "NAN (n-char -sequence-opt)", the first is not to be thought that the following the code should produce infinity and NaN, because the field width covers the prefixes of the matching input sequences:

int r;
double d;
d = 0; r = sscanf("inf", "%2le", &d);
printf("%d %e\n", r, d);
d = 0; r = sscanf("nan", "%2le", &d);
printf("%d %e\n", r, d);

There is also this bit on scanf():

a, e, f, g Corresponds to an optionally signed floating-point, infinity, or NaN number, the format of which coincides with that expected for a sequence of strtod function entities. The corresponding argument should be a pointer to floating.

, 2, , ( "inf" "nan" ), "in" "na" ?

+4
2

scanf " " - , . , , , " ", .

, , , .

, scanf ( 10 ), :

10 & hellip; [ ] , . , : .

" " ; f, :

, strtod.

.

, strtod. strtod , ( ), endptr.

, scanf , . (. ungetc.) , scanf , , , , . strtod, , .

strtod , scanf , . strtod , NUL, NUL . , strtod ; , .

. 1E-@, scanf , getchar '@'. strtod 1.0 endptr, E.

, scanf . 1E-7@, scanf %2f %3f ; %1f 1.0, %4f ( ) .01, @ ( ). %2f, inf nan, , 1E-7: ( ).

, , C . Glibc , glibc, , Linux , gcc clang, clang C, libcxx.

, Windows ( -), , libcrt scanf , . FreeBSD , scanf , .

+3

, :

, .

:

int ch;
int res;
const char *input_fmt;

ch = 0;
input_fmt = "%*d%c";
res = sscanf("123456789012345678901234567890abc", input_fmt, &ch);
printf("%d\t%c\n", res, ch);

// 1      a

%d , 0-9, ch=='a' ; n . input_fmt="%*2d%c":

1      3

, %c 3. "". 12 123456..., %d. :

input_fmt = "%*2d%c";
res = sscanf("1a3456789012345678901234567890bc", input_fmt, &ch);
printf("%d\t%c\n", res, ch);

// 1      a

, %d 2, 1, a .

, inf nan :

double d;
int r;
char s[10];

// 0       0.000000        ""
*s = 0; d = 0; r = sscanf("infinity", "%2le%9s", &d, s);
printf("%d\t%f\t\"%s\"\n", r, d, s);

// 2       inf             "inity"
*s = 0; d = 0; r = sscanf("infinity", "%3le%9s", &d, s);
printf("%d\t%f\t\"%s\"\n", r, d, s);

// 0       0.000000        ""
*s = 0; d = 0; r = sscanf("-infinity", "%3le%9s", &d, s);
printf("%d\t%f\t\"%s\"\n", r, d, s);

// 2       -inf             "inity"
*s = 0; d = 0; r = sscanf("-infinity", "%4le%9s", &d, s);
printf("%d\t%f\t\"%s\"\n", r, d, s);

, , -inf nan. , .

+2

Source: https://habr.com/ru/post/1678492/


All Articles