Проблема с функцией sprintf, последние параметры неверны при записи - PullRequest
0 голосов
/ 20 февраля 2010

Так что я использую sprintf

sprintf(buffer, "%f|%f|%f|%f|%f|%f|%d|%f|%d", x, y, z, u, v, w, nID, dDistance, nConfig);

Но когда я печатаю буфер, я неправильно получаю 2 последних параметра, они, допустим, равны 35,0000 и 0, а в строке они равны 0,00000 и 10332430, и мой буфер достаточно длинный, а все остальные параметры хороши строка

Есть идеи? Есть ли ограничение на длину sprintf или что-то еще?

Я проверил типы всех чисел, и они верны, но проблема, похоже, в dDistance. Когда я удаляю его из спринта, nConfig получает правильное значение в строке, но когда я удаляю nConfig, dDistance все равно не получает правильное значение. Я проверил и dDistance является двойной. Есть идеи?

Поскольку люди, кажется, не верят мне, я сделал это:

char test[255]={0};
int test1 = 2;
double test2=35.00;
int test3 = 0;

sprintf(test,"%d|%f|%d",test1,test2,test3);

и я получаю это в моей строке:

2|0.000000|1078034432

Ответы [ 4 ]

5 голосов
/ 20 февраля 2010

Я бы проверил, чтобы ваши типы аргументов совпадали с вашими строковыми элементами формата.Попытка отобразить double как целочисленный тип (% d) или наоборот может дать вам странный вывод.

2 голосов
/ 20 февраля 2010

Вы уверены, что ваши типы данных соответствуют спецификации вашего формата?

Попробуйте распечатать данные, то есть создайте printf с тем же форматом и посмотрите, что получится:

printf("%f|%f|%f|%f|%f|%f|%d|%f|%d", x, y, z, u, v, w, nID,dDistance, nConfig);

Попробуйте использовать потоки, например

stringstream ss;

ss << x << "|" << y << "|" << z << "|" << u << "|" << v << "|" << w << "|"
   << nID << "|"<< dDistance << "|"<< nConfig;

string s = ss.str();

, а затем сделайте что-нибудь с s;

1 голос
/ 20 февраля 2010

Какого размера long и int?

Если nID - это длинная печать с форматом 'int' и sizeof(int)! = sizeof(long), то с этого момента вы получите несогласованный доступ к данным (в том смысле, что выравнивание неверно).

Какой компилятор вы используете? GCC должен диагностировать проблему без затруднений, если это проблема. Точно так же, если nID - это long long, у вас могут возникнуть проблемы.


Чтобы ответить на ваш вопрос - да, на верхнем пределе длины строки есть нижняя граница, которую sprintf() должен уметь обрабатывать. Это номер 509 для систем C89 и 4095 для систем C99.

Если быть точным, C99 говорит (fprintf(), раздел §7.19.6.1, пункт 15):

Количество символов, которое может быть получено при любом одном преобразовании, должно быть не менее 4095

Нет дополнительной квалификации по sprintf().


С исправленной версией исправленного примера, преобразованного в компилируемый код:

#include <stdio.h>
int main(void)
{
    char  test[255] = {0};
    int    test1 = 2;
    double test2 = 35.00;
    int    test3 = 0;
    sprintf(test, "%d|%f|%d", test1, test2, test3);
    puts(test);
    return(0);
}

Я получаю вывод, который ожидал:

2|35.000000|0

Чтобы получить вывод, который вы показываете, вы должны работать с очень странной настройкой.

  • На какой ты платформе?

Показанное вами поведение указывает на то, что используемая вами функция sprintf() сбита с толку относительно выравнивания или размера чего-либо. У вас есть прототип по объему, то есть вы #include <stdio.h>? С GCC я получаю всевозможные предупреждения, когда опускаю заголовок:

x.c: In function ‘main’:
x.c:8: warning: implicit declaration of function ‘sprintf’
x.c:8: warning: incompatible implicit declaration of built-in function ‘sprintf’
x.c:9: warning: implicit declaration of function ‘puts’

Но даже с test2, переопределенным как float, я получаю правильный результат.

Если я изменю test2 на long double, то получу другой набор предупреждений и другой результат:

x.c: In function ‘main’:
x.c:8: warning: implicit declaration of function ‘sprintf’
x.c:8: warning: incompatible implicit declaration of built-in function ‘sprintf’
x.c:8: warning: format ‘%f’ expects type ‘double’, but argument 4 has type ‘long double’
x.c:9: warning: implicit declaration of function ‘puts’

2|0.000000|0

Это ближе к тому, что вы видите, но далеко не идентично.

Поскольку у нас нет информации о платформе, я подозреваю, что вы работаете с действительно древней (или я имею в виду глючная?) Версией C. Но я все еще в некоторой растерянности, чтобы увидеть, как вы получаете то, что показываете - если только вы не находитесь на машине с прямым порядком байтов (я тестирую на Intel Mac с MacOS X 10.6.2) ... pause ... на машине SPARC под управлением Solaris 10, без #include <stdio.h> и с long double test2 = 35.0;, я получаю:

gcc -O x.c -o x && ./x 
x.c: In function 'main':
x.c:8: warning: incompatible implicit declaration of built-in function 'sprintf'
2|-22446048024026502740613283801712842727785152907992454451420278635613183447049251888877319095301502091725503415850736723945766334416305449970423980980099172087880564051243997662107950451281495566975073444407658980167407319222477077473080454782593800009947058951029590025152409694784570786541673131117073399808.000000|0

Это другое; он также генерирует 321 символ вывода, поэтому там переполнение буфера - лучше использовать 'snprintf()', чтобы этого не происходило. Конечно, когда все объявлено правильно, я получаю ожидаемый результат.

Итак, вы можете опубликовать скомпилированный код, который показывает вашу проблему, вместо фрагмента, который этого не делает? И можете ли вы определить свою платформу - тип компьютера, версию операционной системы, версию компилятора (и, возможно, версию библиотеки C)?

0 голосов
/ 20 февраля 2010

dDistance типа double? Похоже, ваш% f захватывает только четыре байта двойного числа, а затем следующие четыре байта рассматриваются как целое число, а действительное целое значение игнорируется.

Этот вопрос помечен C ++; Вы можете использовать std :: ostringstream, который устранит любые возможные проблемы со строкой преобразования?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...