Почему этот atof() возвращает 0.0 для не-0.0 строковых чисел?
Я должен прочитать строку, как это:
0.000000 0.000000 -1.000000 -1.000000 0.230392 0.562016 -1.000000 -1.000000
С помощью strtok()
и while
цикл, я пытаюсь извлечь каждый чисел с плавающей точкой и сохранить его в моей программе. Существует проблема при преобразовании токена в число с плавающей запятой. Это мой код:
double p;
char* token = strtok(line, " ");
while (token) {
p = atof(token);
printf("atof('%s') = %f\n", token, p);
token = strtok(NULL, " ");
}
Это выводит:
atof('0.000000') = 0,000000
atof('0.000000') = 0,000000
atof('-1.000000') = -1,000000
atof('-1.000000') = -1,000000
atof('0.230392') = 0,000000 <<<---- ???????????
atof('0.562016') = 0,000000 <<<---- ???????????
atof('-1.000000') = -1,000000
atof('-1.000000') = -1,000000
Видишь проблему? Почему atof возвращает 0 при передаче строкового числа от 0 до 1?
2 ответа
atof()
(более конкретно, strtod()
) зависит от региона. Ваш язык использует ,
для обозначения десятичной дроби, в то время как входная строка использует .
указать десятичную точку. поскольку atof()
прекращает анализ первого недопустимого символа, возвращает 0
,
Простое решение заключается в том, чтобы изменить либо языковой стандарт вашего компьютера на другой языковой стандарт, либо изменить строки ввода.
РЕДАКТИРОВАТЬ: Вы можете обновить строку ввода, как это:
void update_string(char *str) {
char *p = str;
while(*p != '\0') {
if(*p == '.')
*p = ',';
p++;
}
Это довольно временное (и некрасивое) решение. Предпочтительным решением является изменение вашего языка. Вы можете сделать это постоянно (обратитесь к документации вашего дистрибутива) или временно.
Чтобы сделать это временно, просто положив LC_NUMERIC="C"
перед командой. Так что если ваша скомпилированная программа называется a.out
, вы бы выполнили это используя:
LC_NUMERIC="C" ./a.out
или с помощью setlocale()
в вашем main()
функция.
Десятичная точка для atof
зависит от локали. В вашем регионе, кажется, десятичная точка ,
в результате чего разбор заканчивается на .
,