我有一个字符串(char *),我需要找到它的基础数据类型,如int,float,double,short,long,或者只是一个包含带或带有数字的字母的字符数组(如SQL中的varchar) 。 例如:
char* str1 = "12312"
char* str2 = "231.342"
char* str3 = "234234243234"
char* str4 = "4323434.2432342"
char* str5 = "i contain only alphabets"
鉴于这些字符串,我需要找到第一个字符串是int类型并将其类型转换为int,依此类推 ex:
int no1 = atoi(str1)
float no2 = atof(str2)
long no3 = atol(str3)
double no4 = strtod(str4)
char* varchar1 = strdup(str5)
澄清一点......
我有一个字符串,其内容可以是字母和/或数字和/或特殊字符。现在,我能够解析字符串和
答案 0 :(得分:1)
首先,检查问题是否尚未解决。可能是您的库函数将字符串转换为数字已经进行了所需的检查。
如果不这样做,你将需要对字符串进行一些模式匹配,这就是正则表达式的用法!
E.g。如果字符串与正则表达式匹配:
[+-]?\d+
然后你知道它是一个int或long。将其转换为long,然后检查其大小。如果你的long可以适合int,则将其转换为int。
你可以对浮点数和双打数做同样的事情,虽然正则表达式有点复杂。
注意尴尬的情况,比如空字符串,单个小数点,数字太长,等等。您还需要决定是否允许使用指数表示法。
答案 1 :(得分:1)
尝试使用sscanf将其变为长版。如果失败,请尝试使用sscanf将其变为双精度数。如果失败,那就是一个字符串。您可以使用%n转换来判断是否已成功使用所有输入。 <limits.h>
和<float.h>
中的常量可以帮助您确定数字结果是否适合您平台上较窄的类型。如果这不是作业,您的目的地类型可能是外部定义的 - 例如通过数据库模式 - 后面的注释无关紧要。
答案 2 :(得分:1)
在C(不是在C ++中)中,我将使用strtod / strol和&lt; limits.h&gt;中的最大值的组合。和&lt; float.h&gt;:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <float.h>
/* Now, we know the following values:
INT_MAX, INT_MIN, SHRT_MAX, SHRT_MIN, CHAR_MAX, CHAR_MIN, etc. */
typedef union tagMyUnion
{
char TChar_ ; short TShort_ ; long TLong_ ; double TDouble_ ;
} MyUnion ;
typedef enum tagMyEnum
{
TChar, TShort, TLong, TDouble, TNaN
} MyEnum ;
void whatIsTheValue(const char * string_, MyEnum * enum_, MyUnion * union_)
{
char * endptr ;
long lValue ;
double dValue ;
*enum_ = TNaN ;
/* integer value */
lValue = strtol(string_, &endptr, 10) ;
if(*endptr == 0) /* It is an integer value ! */
{
if((lValue >= CHAR_MIN) && (lValue <= CHAR_MAX)) /* is it a char ? */
{
*enum_ = TChar ;
union_->TChar_ = (char) lValue ;
}
else if((lValue >= SHRT_MIN) && (lValue <= SHRT_MAX)) /* is it a short ? */
{
*enum_ = TShort ;
union_->TShort_ = (short) lValue ;
}
else if((lValue >= LONG_MIN) && (lValue <= LONG_MAX)) /* is it a long ? */
{
*enum_ = TLong ;
union_->TLong_ = (long) lValue ;
}
return ;
}
/* real value */
dValue = strtod(string_, &endptr) ;
if(*endptr == 0) /* It is an real value ! */
{
if((dValue >= -DBL_MAX) && (dValue <= DBL_MAX)) /* is it a double ? */
{
*enum_ = TDouble ;
union_->TDouble_ = (double) dValue ;
}
return ;
}
return ;
}
void studyValue(const char * string_)
{
MyEnum enum_ ;
MyUnion union_ ;
whatIsTheValue(string_, &enum_, &union_) ;
switch(enum_)
{
case TChar : printf("It is a char : %li\n", (long) union_.TChar_) ; break ;
case TShort : printf("It is a short : %li\n", (long) union_.TShort_) ; break ;
case TLong : printf("It is a long : %li\n", (long) union_.TLong_) ; break ;
case TDouble : printf("It is a double : %f\n", (double) union_.TDouble_) ; break ;
case TNaN : printf("It is a not a number : %s\n", string_) ; break ;
default : printf("I really don't know : %s\n", string_) ; break ;
}
}
int main(int argc, char **argv)
{
studyValue("25") ;
studyValue("-25") ;
studyValue("30000") ;
studyValue("-30000") ;
studyValue("300000") ;
studyValue("-300000") ;
studyValue("25.5") ;
studyValue("-25.5") ;
studyValue("25555555.55555555") ;
studyValue("-25555555.55555555") ;
studyValue("Hello World") ;
studyValue("555-55-55") ;
return 0;
}
结果如下:
[25] is a char : 25
[-25] is a char : -25
[30000] is a short : 30000
[-30000] is a short : -30000
[300000] is a long : 300000
[-300000] is a long : -300000
[25.5] is a double : 25.500000
[-25.5] is a double : -25.500000
[25555555.55555555] is a double : 25555555.555556
[-25555555.55555555] is a double : -25555555.555556
[Hello World] is a not a number
[555-55-55] is a not a number
抱歉我的生锈C.
: - )
因此,实际上,在调用whatIsTheValue之后,您通过MyEnum枚举检索类型,然后根据此枚举中的值,从联合MyUnion中检索正确键入的正确值。
请注意,查找数字是double还是float更复杂,因为差异似乎是精度,即您的数字可以表示为double或float。大多数“十进制实数”数字并不完全可以表示为双数,我不会打扰。
另请注意,有一个catch,因为25.0可以是实数和整数。我比较“dValue ==(double)(long)dValue”,我想你应该知道是否是一个整数,再次,不考虑计算机使用的二进制实数的常见精度问题。
答案 3 :(得分:0)
首先,您应该决定要识别哪些代表。例如,0xBAC0是以十六进制表示的无符号短整数吗? 010(八进制)和1E-2(对于0,01)也是如此。
一旦确定了represantation,就可以使用正则表达式来确定常规表单。例如:
-?\d*.\d*([eE]?[+-]?\d*.\d*)?
是一个浮点数(差不多,它接受奇怪的事情,比如.e-.
你应该定义最适合你的正则表达式)-?\d+
是一个整数0x[0-9A-Fa-f]+
是十六进制常量等等。如果您没有使用正则表达式库,则必须从头开始为这些重新编写一个小的解析器。
现在您可以将其转换为最大可能的类型(例如,long long
表示整数,双精度表示浮点指针),然后使用limits.h
中的值来查看该值是否适合较小的类型
例如,如果整数小于SHRT_MAX
,您可以认为它是short
。
您可能还需要做出任意决定,例如54321只能是unsigned short
,但12345可以是signed short
或unsigned short
。