Возвращаемое значение strtod(), если строка равна нулю

Согласно MSDN:

  • strtod возвращает 0, если преобразование не может быть выполнено или происходит недостаточное заполнение.

Что если моя строка равна нулю (т. Е. 0,0000)? Как я могу узнать, нет ли ошибки при конвертации?

ОК, я использую следующий код для проверки идеи:

char    *Y = "XYZ";
double  MyNum;
char    *MyEndPtr;
int     Err_Conversion = 0;

errno = 0;  //reset
MyNum = strtod (Y, &MyEndPtr);

if ( (MyNum == 0) && (errno != 0) && (strcmp(Y, MyEndPtr) == 0) )
        { Err_Conversion = 1;   }

Я вижу, что MyNum = 0, но никогда не вижу содержимого Y, скопированного в MyEnPtr, или errno = 0 в этой принудительной ошибке. Любая идея?

2 ответа

Использовать str_end параметр функции. Например:

const char* str = "123junk";
char* str_end;
double d = strtod(str, &str_end);
// Here:
//   d will be 123
//   str_end will point to (str + 3) (the 'j')

// You can tell the string has some junk data if *str_end != '\0'
if (*str_end != '\0') {
    printf("Found bad data '%s' at end of string\n", str_end);
}

Если преобразование полностью не удается, str будет равно str_end:

const char* str = "junk";
char* str_end;
double d = strtod(str, &str_end);
// Here:
//   d will be 0 (conversion failed)
//   str_end will equal str

if (str == str_end) {
    printf("The string doesn't start with a number!\n");
}

Вы можете объединить эти два метода, чтобы убедиться, что строка была (полностью) успешно преобразована (то есть путем проверки str != str_end && *str_end == '\0')

Подпись есть (дай или возьми restrict ключевые слова):

 double strtod(const char *nptr, char **endptr);

Если вы передаете ненулевой указатель в качестве второго аргумента, он будет возвращен со значением nptr если бы он не мог выполнить преобразование. Если во входной строке обнаружен подлинный ноль, то значение сохраняется в *endptr не будет nptr,

char *end;
const char *data = "0.00000";

errno = 0;
double d = strtod(data, &end);
if (end != data)
    ...a conversion was performed...
else
    ...trouble...

Вы также можете посмотреть на errno, но вам нужно обнулить его перед вызовом, потому что в стандартной библиотеке C или в библиотеке POSIX нет функций errno в ноль.

Стандарт гласит:

Если предметная последовательность пуста или не имеет ожидаемой формы, преобразование не выполняется; значение nptr хранится в объекте, указанном endptr, при условии, что endptr не является нулевым указателем

Возвращает

Функции возвращают преобразованное значение, если оно есть. Если преобразование не может быть выполнено, возвращается ноль. Если корректное переполнение значения и округление по умолчанию действуют (7.12.1), возвращается плюс или минус HUGE_VAL, HUGE_VALF или HUGE_VALL (в соответствии с типом возврата и знаком значения), и значение макроса ERANGE сохраняется в errno, Если результат недооценен (7.12.1), функции возвращают значение, величина которого не больше, чем наименьшее нормализованное положительное число в типе возврата; будь то errno получает значение ERANGE, определяемое реализацией.

Другие вопросы по тегам