문제

ANSI C만 사용하여 C 스타일 문자열이 정수인지 실수(예: float/double)인지 확인하는 가장 좋은 방법은 무엇입니까?

도움이 되었습니까?

해결책

atoi 및 atof는 실패 시 0을 반환하므로 사용하지 마세요.마지막으로 확인했을 때 0은 유효한 정수 및 부동 소수점이므로 유형을 결정하는 데 사용되지 않습니다.

strto{l,ul,ull,ll,d} 함수를 사용하세요. 실패 시 errno를 설정하고 변환된 데이터가 끝난 위치도 보고합니다.

strtoul : http://www.opengroup.org/onlinepubs/007908799/xsh/strtoul.html

이 예에서는 문자열에 변환할 단일 값이 포함되어 있다고 가정합니다.

#include <errno.h>

char* to_convert = "some string";
char* p = to_convert;
errno = 0;
unsigned long val = strtoul(to_convert, &p, 10);
if (errno != 0)
    // conversion failed (EINVAL, ERANGE)
if (to_convert == p)
    // conversion failed (no characters consumed)
if (*p != 0)
    // conversion failed (trailing data)

먼저 errno를 0으로 설정하는 것을 잊었다는 점을 지적해준 Jonathan Leffler에게 감사드립니다.

다른 팁

사용 스캔프, 를 사용하면 atoi 및 atof 솔루션의 경우처럼 특별한 경우 0을 사용하지 않고도 문자열이 float인지 int인지 또는 무엇이든 확인할 수 있습니다.

다음은 몇 가지 예제 코드입니다.

int i;
float f;
if(sscanf(str, "%d", &i) != 0) //It's an int.
  ...
if(sscanf(str "%f", &f) != 0)  //It's a float.
  ...

atoi 및 atof는 변환할 수 없는 경우 0을 변환하거나 반환합니다.

나는 strto{l,ul,ull,ll,d} 함수가 가장 좋은 방법이라는 Patrick_O의 의견에 동의합니다.하지만 지켜봐야 할 몇 가지 사항이 있습니다.

  1. 함수를 호출하기 전에 errno를 0으로 설정하십시오.어떤 기능도 당신을 위해 그렇게 하지 않습니다.
  2. 연결된 Open Group 페이지(Patrick도 연결했다는 사실을 알기 전에 방문함)에서는 errno가 설정되지 않았을 수 있다고 지적합니다.값이 범위를 벗어나면 ERANGE로 설정됩니다.그것 5월 설정됩니다(그러나 동등하게 5월 ~ 아니다 인수가 유효하지 않은 경우)를 EINVAL로 설정합니다.

현재 작업에 따라 반환된 변환 포인터의 끝에서 후행 공백을 건너뛰고 마지막 문자가 종료 null '\0'이 아닌 경우 불평(거부)하도록 조정하는 경우도 있습니다.아니면 엉성해서 끝에 쓰레기가 나타나도록 할 수도 있고, 킬로바이트, 메가바이트, 기가바이트, 테라바이트 등에 대해 'K', 'M', 'G', 'T'와 같은 선택적 승수를 허용할 수도 있습니다.또는 상황에 따른 기타 요구 사항.

나는 당신이 문자열을 살펴보고 어떤 것이 있는지 확인할 수 있다고 가정합니다. . 그 안에 있는 문자.하지만 그것은 내 머리 속에 가장 먼저 떠오른 것이므로 더 확실하게 할 수 있는 다른 (더 나은) 방법이 있을 것이라고 확신합니다.

정수를 확인하려면 strtol/strtoll(atoi 아님)을 사용하세요.double을 확인하려면 strtof/strtod(atof 아님)를 사용하세요.

atoi 및 atof는 문자열의 초기 부분을 변환하지만 문자열 전체를 사용했는지 여부는 알려주지 않습니다.strtol/strtod는 문자 변환 후 추가 정크가 있는지 여부를 알려줍니다.

따라서 두 경우 모두 null이 아닌 TAIL 매개변수를 전달하고 이 매개변수가 문자열의 끝(즉, **TAIL == 0)을 가리키는지 확인해야 합니다.또한 언더플로 및 오버플로에 대한 반환 값을 확인하십시오(자세한 내용은 매뉴얼 페이지 또는 ANSI 표준 참조).

또한 strd/strtol은 초기 공백을 건너뛰므로 초기 공백이 있는 문자열을 잘못된 형식으로 처리하려면 첫 번째 문자도 확인해야 합니다.

그것은 실제로 당신이 처음에 질문하는 이유에 달려 있습니다.

숫자만 구문 분석하고 부동 소수점인지 정수인지 모르는 경우 부동 소수점만 구문 분석하면 정수도 올바르게 구문 분석됩니다.

분류를 위해 실제로 유형을 알고 싶다면 가장 관련성이 있다고 생각되는 순서대로 유형을 테스트하는 것을 고려해야 합니다.정수를 구문 분석해 보고, 그렇게 할 수 없으면 부동소수점을 구문 분석해 보세요.(그 반대의 경우에는 수레가 조금 더 많이 생성됩니다...)

atoi 및 atof는 뒤에 숫자가 아닌 문자가 있어도 숫자를 변환합니다.그러나 strtol 및 strtod를 사용하면 선행 공백과 선택적 기호를 건너뛸 뿐만 아니라 숫자에 없는 첫 번째 문자에 대한 포인터도 남게 됩니다.그러면 나머지가 공백임을 확인할 수 있습니다.

글쎄, strtoul과 같은 새로운 함수를 사용하고 싶지 않다면 다른 strcmp 문을 추가하여 문자열이 0인지 확인할 수 있습니다.

즉.

if(atof(token) != NULL || strcmp(token, "0") == 0)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top