字符及字符串操作(2)——<stdlib.h>中C/C++库函数详解及实例

文章详细介绍了C语言中将字符串转换为不同数值类型的函数,包括atof、atoi、atol、atoll用于转换浮点数、整数和长整型,以及strtod、strtof、strtol和strtoul支持科学计数法和不同进制转换的函数。每个函数的源码、使用示例和功能特性都得到了详尽的解释。
摘要由CSDN通过智能技术生成

目录

1.atof:将字符串转换为浮点(double)类型

2.atoi:将字符串转换为整形(int)类型

3.atol:将字符串转换为长整形(long int)类型 

4.atoll:将字符串转换为长长整形(long long)类型 

5.strtod:将字符串转换为浮点(double )类型 

6.strtof:将字符串转换为浮点(float )类型 

7.strtol:将字符串转换为长整型(long int)类型 

8.strtoul:字符串转换成无符号长整型(unsigned long )函数


1.atof:将字符串转换为双精度浮点(double)类型

函数声明:double atof(const char *s)。

函数说明:将字符串s转换为双精度浮点数据,并返回。只能转换十进制,不能转换科学计数法字符串。如需转换科学计数的字符串可参照strtod。

函数源码:

double atof(const char *s) 
{
    double val, power;
    int i, sign;
     /* 跳过空白符 */
    for (i = 0; isspace(s[i]); i++)
            ;
     /* 符号位 */
     sign = (s[i] == '-') ? -1 : 1;
     if (s[i]  == '+' || s[i] == '-')
        i++;
      /* 整数数据*/
      for (val = 0.0; isdigit(s[i]); i++)
           val = 10.0 * val +(s[i]-'0');
       /* 小数点*/
       if(s[i] == '.')
            i++;
        /* 小数数据*/
        for (power = 1.0; isdigit(s[i]); i++) 
        {
            val = 10.0 * val + (s[i] - '0');
            power *= 10.0;
        }
        return sign * val / power;
    }

2.atoi:将字符串转换为整形(int)类型

函数声明:int atoi(const char *str) 。

函数说明:将字符串str转换为int类型,并返回。只能转换10进制数据。如需转换其他进制,参照strtol。

函数源码:

int atoi(const char *str)
{
    int result;
    int signal = 1;

    if(*str=='-'||*str=='+')
    {
        if(*str=='-') signal = -1;
        str++;
    }

    if(!isdigit(*str))
    {
        return 0;
    }        
    
    while(isdigit(*str)) result = result*10+(*str++ -'0'); /*转换*/
    
    return signal*result;
}

3.atol:将字符串转换为长整形(long int)类型 

函数声明:long int atol(const char *str) 。

函数说明:将字符串str转换为long int类型,并返回。只能转换10进制数据。如需转换其他进制,参照strtol。

函数源码:

long int atol(const char *str)
{
    long int result;
    long int signal = 1;

    if(*str=='-'||*str=='+')
    {
        if(*str=='-') signal = -1;
        str++;
    }

    if(!isdigit(*str))
    {
        return 0;
    }        
    
    while(isdigit(*str)) result = result*10+(*str++ -'0'); /*转换*/
    
    return signal*result;
}

4.atoll:将字符串转换为长长整形(long long)类型 

函数声明:long long atoll(const char *str) 。

函数说明:将字符串str转换为long long 类型,并返回。只能转换10进制数据。

函数源码:

long long atoll(const char *str)
{
    long long result;
    long long signal = 1;

    if(*str=='-'||*str=='+')
    {
        if(*str=='-') signal = -1;
        str++;
    }

    if(!isdigit(*str))
    {
        return 0;
    }        
    
    while(isdigit(*str)) result = result*10+(*str++ -'0'); /*转换*/
    
    return signal*result;
}

5.strtod:将字符串转换为双精度浮点(double )类型 

函数声明:double strtod(const char *s, char **endptr)

函数说明:函数扫描参数s处的字符串,跳过空格字符,直到遇上数字或正负符号才开始做转换,出现非法字符结束转换,并返回转换结果。若endptr不为NULL,end负责传出导致转换终止的异常字符。该方式可以转换科学计数法字符串。

函数源码:

double strtod(const char* s, char** endptr)
{
	const char*  p = s;
	double  value = 0.0;
	int                   sign = 0;
	long double           factor;
	unsigned int          expo;

	while (isspace(*p)) p++;//跳过前面的空

	if (*p == '-' || *p == '+') sign = *p++;//符号判断

	while (isdigit(*p)) value = value * 10 + (*p++ - '0');//转换整数部分

   // 小数点及小数部分
	if (*p == '.')
	{
		factor = 1.0; p++;
		while (isdigit(*p))
		{
			factor *= 0.1;
			value += (*p++ - '0') * factor;
		}
	}
	// 科学计数法
	if ((*p == 'e') || (*p == 'E'))
	{
		expo = 0;
		factor = 10.L;
		switch (*++p)
		{
		case '-':
			factor = 0.1;
		case '+':
			p++;
			break;
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			break;
		default:
			value = 0.L;
			p = s;
			goto done;
		}
		while (isdigit(*p)) expo = 10 * expo + (*p++ - '0');
		while (1)
		{
			if (expo & 1) value *= factor;

			if ((expo >>= 1) == 0) break;

			factor *= factor;
		}
	}
	// 返回异常字符
done:
	if (endptr != 0) *endptr = (char*)p;
	return (sign == '-' ? -value : value);
}

示例:

    char flag;
	char *pflag = &flag;
	double c;
	c=strtod("    +1.000E-5",&pflag);
	printf("科学计数:%lf\n",c);
	c = strtod("    +100.001", &pflag);
	printf("十进制浮点:%lf", c);

执行结果:

6.strtof:将字符串转换为浮点(float )类型 

函数声明:float strtof(const char *start, char **end)

函数说明:函数扫描参数start处的字符串,跳过空格字符,直到遇上数字或正负符号才开始做转换,出现非法字符结束转换,并返回转换结果。若end不为NULL,end负责传出导致转换终止的异常字符。该方式可以转换科学计数法字符串。

函数源码:

float strtof(const char *start, char **end)
{
	double		dresult;
	float		fresult;

	dresult = strtod(start, end);
	fresult = (float) dresult;

	return fresult;
}

示例及执行结果可参照 strtod

7.strtol:将字符串转换为长整型(long int)类型 

函数声明:long int strtol(const char *start, char **end, int base)

函数说明:将字符串从start转换为长整型值,其中进行转换字符串必须是长整型的字符表示格式,如果字符串中有非法的非数字字符,则第二个参数end将负责获取该非法字符。

base表示进制:0-自适应8/10/16进制,x-强制x进制。

该方法支持10进制、16进制、8进制、其他进制格式转换。当数据越限时,打印极限值,正数极限为2147483647(0x7FFFFFFF),负数极限为-2147483648(-0x80000000)。

函数源码:

#define LONG_MAX 2147483647L/*0x7FFFFFFF*/
#define LONG_MIN (-2147483647L-1L) /*-0x80000000*/
long int strtol(const char *start, char **end, int base)
{
	const char *p = start;
	unsigned long ret;
	int ch;
	unsigned long Overflow;
	int sign = 0,flag, LimitRemainder;
	// 去空格
 	do{ch = *p++;} while(isspace(ch));
	// 符号判断
	if (ch =='-'){sign = 1;ch = *p++;}
	else if (ch == '+'){ch = *p++;}
	// 进制识别(8\10\16)
	if ((base ==0||base == 16)&&ch =='0'&&(*p =='x'||*p =='X'))
	{ch = p[1];p += 2;base = 16;}
	if(base ==0) base = ch == '0' ? 8 : 10;
	// 门槛
	Overflow = sign ? -(unsigned long)LONG_MIN:LONG_MAX;
	LimitRemainder = Overflow % (unsigned long)base;
	Overflow /= (unsigned long)base;

	for (ret = 0,flag = 0;; ch = *p++)
	{
		if(isdigit(ch)) ch -= '0';//数字
		else if (isalpha(ch)) ch -= isupper(ch) ? 'A' - 10 : 'a' - 10;//16进制字母
		else break;          //非法字符
		if (ch>= base) break;//越界
		// 
		if (flag< 0 || ret > Overflow || (ret == Overflow && ch >LimitRemainder)){flag = -1;}//越限
		else{flag = 1;ret *= base;ret += ch;} // 计算结果
	}
    // 越限数据
	if(flag<0) ret =sign?LONG_MIN:LONG_MAX;
    // 正常数据
	else if (sign)ret = -ret;
	// 记录异常字符
	if(end !=0)*end = (char*)(flag?(p-1):start);
	return ret;
}

示例:

	char rtn;
	char *prtn = &rtn;
	long int rec = strtol("   0x6bcdabcd", &prtn, 0);
	printf("自适应16进制:%x\n", rec);
	rec = strtol("   012345677", &prtn, 0);
	printf("自适应8进制:%o\n", rec);
	rec = strtol("   -12345677", &prtn, 0);
	printf("自适应10进制:%d\n", rec);
	rec = strtol("   -25623", &prtn, 7);
	printf("强制7进制:%d\n", rec);
	rec = strtol("   101010", &prtn, 2);
	printf("强制2进制:%d\n", rec);

执行结果:

8.strtoul:字符串转换成无符号长整型(unsigned long )函数

函数声明:unsigned long strtoul(const char *start, char **end, int base)

函数说明:将字符串从start转换为无符号长整型值,其中进行转换字符串必须是无符号长整型的字符表示格式,如果字符串中有非法的非数字字符,则第二个参数end将负责获取该非法字符。

base表示进制:0-自适应8/10/16进制,x-强制x进制。

该方法支持10进制、16进制、8进制、其他进制格式打印,当数据越限时,打印最大值0xffffffff。

函数源码:

#define LONG_MAX  (0xffffffff)
unsigned long strtoul(const char *start, char **end, int base)
{
	const char *p = start;
	unsigned long ret;
	int ch;
	unsigned long Overflow;
	int flag, LimitRemainder;
	// 去空格
 	do{ch = *p++;} while(isspace(ch));
	// 进制识别(8\10\16)
	if ((base ==0||base == 16)&&ch =='0'&&(*p =='x'||*p =='X'))
	{ch = p[1];p += 2;base = 16;}
	if(base ==0) base = ch == '0' ? 8 : 10;
	// 门槛
	Overflow = LONG_MAX ;
	LimitRemainder = Overflow % (unsigned long)base;
	Overflow /= (unsigned long)base;

	for (ret = 0,flag = 0;; ch = *p++)
	{
		if(isdigit(ch)) ch -= '0';//数字
		else if (isalpha(ch)) ch -= isupper(ch) ? 'A' - 10 : 'a' - 10;//16进制字母
		else break;          //非法字符
		if (ch>= base) break;//越界
		// 
		if (flag< 0 || ret > Overflow || (ret == Overflow && ch >LimitRemainder)){flag = -1;}//越限
		else{flag = 1;ret *= base;ret += ch;} // 计算结果
	}
	if(flag<0) ret =LONG_MAX;
	// 记录异常字符
	if(end !=0)*end = (char*)(flag?(p-1):start);
	return ret;
}

示例:

	char rtn;
	char *prtn = &rtn;
	unsigned long rec = strtoul("   0xabcdabcd", &prtn, 0);
	printf("自适应16进制:%x\n", rec);
	rec = strtoul("   012345677", &prtn, 0);
	printf("自适应8进制:%o\n", rec);
	rec = strtoul("   12345677", &prtn, 0);
	printf("自适应10进制:%d\n", rec);
	rec = strtoul("   25623", &prtn, 7);
	printf("强制7进制:%d\n", rec);
	rec = strtoul("   101010", &prtn, 2);
	printf("强制2进制:%d\n", rec);

执行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿来不是梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值