Может ли printf () выдать "-.5" для значения (-0.5)? - PullRequest
5 голосов
/ 06 октября 2010

т.е. можно ли printf сказать, что он должен игнорировать ноль, когда он предшествует десятичной запятой?

Ответы [ 6 ]

3 голосов
/ 07 октября 2010

Со всеми вещами, указанными в ISO C99, это невозможно.Документация для спецификаторов преобразования гласит:

f, F: [...] Если появляется знак десятичной точки, перед ним должна быть хотя бы одна цифра.[...]

e, E: [...] одна цифра (ненулевая, если аргумент ненулевой) перед символом десятичной точки [...]

g, G: [...] преобразуется в стиль f или e [...]

Поскольку другие спецификаторы преобразования не будут печатать десятичное число с плавающей запятой,это невозможно вообще.Если вы не найдете расширение поставщика, которое вводит другой спецификатор преобразования.Но тогда ваша программа больше не будет строго верной C.

Лучший обходной путь, который приходит мне в голову:

double number = 0.5;
char buf[80];
char *number = buf;
if (snprintf(buf, sizeof buf, "%f", number) <= 0)
  goto cannot_happen;

while (*number == '0')
  number++;
printf("%s\n", number);
2 голосов
/ 06 октября 2010

Конечно, можно, но, боюсь, вы не будете слишком довольны моим ответом:

printf("-.5", -0.5);
1 голос
/ 06 октября 2010

Одним словом: нет ...

0 голосов
/ 07 октября 2010

Конвертируйте ваш двойник или число с плавающей точкой в ​​символ, тогда:

while (*yourChar != '\0') {
    if (yourDoubleBeforeConversion > 1.0 && yourDoubleBeforeConversion < -1.0) {
        continue;
    }
    if(*yourChar == '.') {
        yourChar--;
        *yourChar = '';
    }
    else {
    }
}

Explination:

  1. цикл while определяет, когда заканчивается символ.
  2. Если ваш дубль больше 1, тогда нет смысла обрезать.
  3. Если не продолжать проверять ".".
  4. Когда один найден, идите раньше и удалите ноль.
0 голосов
/ 06 октября 2010

Да.Используйте спецификатор формата %g вместо %f, т.е. printf("%g", -0.5);

Если вы недовольны тем, как %g печатает некоторые числа в экспоненциальной записи, альтернативой является использование snprintf длязаписать во временный строковый буфер, а затем подсчитать количество нулей в конце перед записью его без printf("%.*s", num_nonzero_places, tmp);, или вы можете просто удалить нули и использовать fputs.

Теперь я понимаювопрос в том, чтобы убрать начальный ноль, а не конечные нули.В этом случае лучший способ, который я знаю, - это использовать snprintf для записи во временную строку, а затем пропустить первый символ при его записи, если этот символ равен «0».Вам также нужно заменить знак «-», если значение отрицательное.Один из способов сделать это:

snprintf(tmp, sizeof tmp, "%+f", val);
printf("%.*s%s", tmp[0]=='-', tmp, tmp+1+(tmp[1]=='0'));
0 голосов
/ 06 октября 2010

См. printf spec и раздел точности. Вы можете сделать printf("%+0.4f", -0.5);

...