2014-02-11 2 views
0

Я имею дело с char [], содержащим текст, который должен представлять собой двойное числовое значение или длинное число.
Мне нужно написать функцию, которая определяет, какой из перечисленных типов данных представляется (если есть).Обнаружение, если строка является двойной или длинной в C

Я думал об использовании strtol() и проверял, не удается ли он разобрать всю строку, и если это не удается, используйте strtod().

Я был бы рад узнать, есть ли лучший вариант для этого. Спасибо.

+4

['strtol'] (http://en.cppreference.com/w/c/string/byte/strtol) и [' strtod'] (http://en.cppreference.com/w/c/string/byte/strtof) в значительной степени отвечают здесь. –

ответ

2

Я думал об использовании strtol() и проверял, не удается ли разобрать всю строку, и если это не удается, используйте strtod().

Я думаю, что это хорошая идея, и я не думаю, что есть лучший. Реализация собственной процедуры синтаксического анализа обычно является плохим.

Я бы обрезал строку из конечных пробелов перед вызовом strtol, чтобы избежать ложных негативов.

+0

'strtol()' не заботится о завершении пробела; он оставляет его как часть неинтерпретированной части строки. –

+0

@JonathanLeffler Если есть пробел в пробеле, 'strtol' не будет анализировать всю строку, он остановится в первом пробеле, тем самым« провалив », чтобы проанализировать всю строку, а значит, и false. –

-2
You can use the following code to detect that. 

char* isDouble = strchr(string, '.'); 
if (isDouble) { 
    // is Double here 
}else { 
    // is long here 
} 
+0

проблема в том, что это зависит от региона, поэтому вы не можете предположить, что поплавок всегда имеет "." это может быть и «,». –

+0

Как насчет '1E-6'? Нет десятичных точек, но он представляет собой двойной. –

1

strtol() и strtod() это правильный подход. Обязательно используйте errno для обнаружения целочисленного переполнения. 2 автономные функции следуют:

int Is_long(const char *src, long *dest) { 
    char *endptr; 
    // Clear, so it may be tested after strtol(). 
    errno = 0; 
    // Using 0 here allows 0x1234, octaland decimal 1234. 
    long num = strtol(src, &endptr, 0); 
    // If +/- overflow, "" or has trailing text ... 
    if (errno || endptr == src || *endptr != '\0') { 
    return 0; 
    } 
    if (dest) *dest = num; 
    return 1; 
} 

int Is_double(const char *src, double *dest) { 
    char *endptr; 
    // In this case, detecting over/undeflow IMO is not a concern, so ignore it. 
    double num = strtod(src, &endptr); 
    // If "" or has trailing text ... 
    if (endptr == src || *endptr != '\0') { 
    return 0; 
    } 
    if (dest) *dest = num; 
    return 1; 
} 

@Klas Lindbäck действительно приносит хорошую точку, что делать конечные пробельные. Этот ответ предполагает, что он недействителен.

Смежные вопросы