C言語は文字列が数字であるか否かを判断する
2516 ワード
文字列が数字かどうかを判断するのは簡単に聞こえますが、実現するのは少し難しいです.最近、次のように書きました.
is_number(char*)関数は、文字列が数値であるかどうかを判断します.そうでない場合は0を返します.整数の場合は、1を返します.16進数の整数の場合は、2を返します.小数であれば3を返します.
テストプログラムを作成します.
運転、「テストOK」
#define IS_BLANK(c) ((c) == ' ' || (c) == '\t')
#define IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
#define IS_ALPHA(c) ( ((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z') )
#define IS_HEX_DIGIT(c) (((c) >= 'A' && (c) <= 'F') || ((c) >= 'a' && (c) <= 'f'))
/* Whether string s is a number.
Returns 0 for non-number, 1 for integer, 2 for hex-integer, 3 for float */
int is_number(char * s)
{
int base = 10;
char *ptr;
int type = 0;
if (s==NULL) return 0;
ptr = s;
/* skip blank */
while (IS_BLANK(*ptr)) {
ptr++;
}
/* skip sign */
if (*ptr == '-' || *ptr == '+') {
ptr++;
}
/* first char should be digit or dot*/
if (IS_DIGIT(*ptr) || ptr[0]=='.') {
if (ptr[0]!='.') {
/* handle hex numbers */
if (ptr[0] == '0' && ptr[1] && (ptr[1] == 'x' || ptr[1] == 'X')) {
type = 2;
base = 16;
ptr += 2;
}
/* Skip any leading 0s */
while (*ptr == '0') {
ptr++;
}
/* Skip digit */
while (IS_DIGIT(*ptr) || (base == 16 && IS_HEX_DIGIT(*ptr))) {
ptr++;
}
}
/* Handle dot */
if (base == 10 && *ptr && ptr[0]=='.') {
type = 3;
ptr++;
}
/* Skip digit */
while (type==3 && base == 10 && IS_DIGIT(*ptr)) {
ptr++;
}
/* if end with 0, it is number */
if (*ptr==0)
return (type>0) ? type : 1;
else
type = 0;
}
return type;
}
is_number(char*)関数は、文字列が数値であるかどうかを判断します.そうでない場合は0を返します.整数の場合は、1を返します.16進数の整数の場合は、2を返します.小数であれば3を返します.
テストプログラムを作成します.
#include <stdio.h>
#include <assert.h>
int main(int argc, char**argv)
{
assert( is_number(NULL) ==0 );
assert( is_number("") ==0 );
assert( is_number("9a") ==0 );
assert( is_number("908") ==1 );
assert( is_number("-908") ==1 );
assert( is_number("+09") ==1 );
assert( is_number("-+9") ==0 );
assert( is_number(" 007") ==1 );
assert( is_number("0x9a8F") ==2 );
assert( is_number("-0xAB") ==2 );
assert( is_number("-9.380") ==3 );
assert( is_number("-0xFF.3") ==0 );
printf("test OK
");
}
運転、「テストOK」