При преобразовании двойного числа в строку, каким может быть первый символ строки?
Легко генерировать "0123456789-+ iInN"
. Но возможны и другие char
, в зависимости от того, как далеко мы хотим его растянуть.
Очевидно, это может быть одно из следующих: 0-9
, -
, .
, но так какздесь мы используем математические операции с плавающей запятой, возможно, есть больше символов, которые могут оказаться в буфере [0], например I
для Inf
или N
для NaN
и, возможно, даже больше?
snprintf(buf, n, "%.14g", d);
Когда n = 1
, ожидайте buf[0] == '\0'
Когда n = 0
, ожидайте, что buf[0]
не изменится, поэтому любой *Здесь возможно значение 1032 * char
.
С "%.14g"
Я бы не ожидал 'I'
или 'N'
, но 'i'
и 'n'
.
"%.14G"
будет производить 'I'
и 'N'
.
С этим форматом не начинается '.'
.
С другими локалями , (исследование setlocale()
), '-'
можетбыть чем-то другим. Я не знаю ни одной локали, которая бы это делала.
Другие форматы
С другим форматом "% something [gefaGefa]"
строки:
Первый символ может бытьпробел ' '
или '+'
. Как и '-'
, это может варьироваться в зависимости от locale .
Если возможен ведущий '.'
(я уверен, что это невозможно в стандартных форматах), другие локали могут использовать альтернативныенапример, ','
.
При использовании форматов, специфичных для реализации, возможен любой начальный символ.
В недопустимых форматах возможен любой начальный символ из-за неопределенного поведения .
#include <stdio.h>
int main(void) {
char s[1000];
double inf = strtod("inf", 0);
double nan = strtod("nan", 0);
snprintf(s, sizeof s, "%g\n", 0.0); printf("%3d %.1s\n", s[0], s);
snprintf(s, sizeof s, "%g\n", 9.0); printf("%3d %.1s\n", s[0], s);
snprintf(s, sizeof s, "%g\n", -1.0); printf("%3d %.1s\n", s[0], s);
snprintf(s, sizeof s, "%+g\n", +1.0); printf("%3d %.1s\n", s[0], s);
snprintf(s, sizeof s, "%g\n", inf); printf("%3d %.1s\n", s[0], s);
snprintf(s, sizeof s, "%G\n", inf); printf("%3d %.1s\n", s[0], s);
snprintf(s, sizeof s, "%g\n", nan); printf("%3d %.1s\n", s[0], s);
snprintf(s, sizeof s, "%G\n", nan); printf("%3d %.1s\n", s[0], s);
snprintf(s, sizeof s, "%5g\n", 1.0); printf("%3d %.1s\n", s[0], s);
snprintf(s, 1, "%g\n", 1.0); printf("%3d %.1s\n", s[0], s);
s[0] = 'z';
snprintf(s, 0, "%g\n", 1.0); printf("%3d %.1s\n", s[0], s);
return 0;
}
Вывод
48 0
57 9
45 -
43 +
105 i
73 I
110 n
78 N
32
0
122 z
Стандартизировано ли поведение snprintf в этой ситуации на разных компиляторах и платформах?
Да. Совместимые возможности включают "0123456789-+ iInN"
. Некоторые компиляторы могут добавлять дополнительные определенные реализации.
где находится спецификация (?)
Ищите спецификации C. Последний - C17
Где найти текущие стандартные документы C или C ++?
Подробности:
infinity --> [-]inf or [-]infinity (efga) or uppercase version (EFGA)
nan --> [-]nan or [-]nan(n-char-sequence) or uppercase prefix version
%f --> [−]ddd.ddd,if a decimal-point character appears,at least one digit appears before it.
%F --> like %f
%e --> [−]d.ddd e±dd
%e --> like %e, but with E
%g --> converted in style f or e
%G --> converted in style F or E
%a --> [−]0xh.hhhh p±d
%A --> like %a, but with X,P