나는 이중 숫자 값 또는 긴 숫자를 나타내는 텍스트를 포함하는 char []를 처리하고 있습니다.
위의 데이터 유형 (있는 경우)을 나타내는 함수를 작성해야합니다.문자열이 double 또는 long C인지 감지
strtol()을 사용하여 전체 문자열을 구문 분석하지 못했는지 확인한 다음 strtod()를 사용하여 실패하면 오류가 있는지 확인했습니다.
더 나은 옵션이 있는지 확인해 드리겠습니다. 감사합니다. .
나는 이중 숫자 값 또는 긴 숫자를 나타내는 텍스트를 포함하는 char []를 처리하고 있습니다.
위의 데이터 유형 (있는 경우)을 나타내는 함수를 작성해야합니다.문자열이 double 또는 long C인지 감지
strtol()을 사용하여 전체 문자열을 구문 분석하지 못했는지 확인한 다음 strtod()를 사용하여 실패하면 오류가 있는지 확인했습니다.
더 나은 옵션이 있는지 확인해 드리겠습니다. 감사합니다. .
나는 strtol()을 사용하여 전체 문자열을 분석하지 못했고, 실패 할 경우 strtod()를 사용하는 방법을 생각했다.
나는 좋은 생각이라고 생각하며, 더 좋은 생각은 없다. 자신의 구문 분석 루틴을 구현하는 것은 일반적으로 나쁜 생각입니다.
잘못된 음수를 피하기 위해 strtol
을 호출하기 전에 후행 공백에서 문자열을 자릅니다.
'strtol()'은 후행 공백을 신경 쓰지 않는다; 그것은 문자열의 해석되지 않은 부분의 일부로 남겨 둡니다. –
@JonathanLeffler 후행 공백이 있으면'strtol'은 전체 문자열을 구문 분석하지 않습니다. 그러면 첫 번째 공백에서 멈추고 전체 문자열을 구문 분석하지 않으므로 false negative가됩니다. –
You can use the following code to detect that.
char* isDouble = strchr(string, '.');
if (isDouble) {
// is Double here
}else {
// is long here
}
문제는 지역에 따라 다르므로 플로트에 항상 "."이 있다고 가정 할 수 없습니다. 그것은 ","일 수도 있습니다. –
'1E-6'은 어떻습니까? 소수점은 없지만 이중을 나타냅니다. –
strtol()
및 strtod()
이 올바른 접근법입니다. 정수 넘침을 감지하려면 errno
을 사용해야합니다. 이 독립형 기능은 다음과 같습니다
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 린드 백은 공백을 후행에 대해 무엇을 해야할지의 좋은 점을 가지고 않습니다. 이 답변은 그것이 유효하지 않다고 가정합니다.
['strtol'] (http://en.cppreference.com/w/c/string/byte/strtol) 및 ['strtod'] (http://en.cppreference.com/w/c/string/byte/strtof) 함수는 여기에 대한 답입니다. –