C和C++中的字符串和数字转换

来源:互联网 发布:php 文件名截断 编辑:程序博客网 时间:2024/06/10 04:35

在做题时经常会遇到字符串和数字转换,当然方法也各不相同,在此我想把各种方法的特点和利弊总结一下。

测试程序示例:
以下测试结果有偶然性,仅供参考。

#include<iostream>#include<time.h>#include<stdlib.h>using namespace std;int main(){    char *a = "12345.6";    double num = 11;    int t_start, t_end;    t_start = clock();    for (int i = 0; i < 100000; ++i)    {        num = atoi(a);    }    t_end = clock();    cout <<"time: "<<t_end - t_start << endl;    cout << "result: "<<num;    getchar();    return 0;}

一、C语言中的标准库函数
参考资料
http://blog.csdn.net/sunquana/article/details/14645079
http://www.jb51.net/article/58452.htm
头文件:# include <stdlib.h>
[tip: 命名规则是:ascii to int/float/long int 等]
接收的格式是字符数组名或指针。
1. atoi() 将字符串转换为整型值

char *a = "12345.6";num = atoi(a);

转换100000次耗时约20毫秒,转换的数字越大,耗时越长。
可以顺利转换整数,输入小数时会忽略小数点后的部分不会四舍五入,输入123a456等内容是,只会输出合法的前几位,比如输出123,如果从第一个字符开始就不合法,会输出0,当超出int范围时得到2147483647,也就是int能表示的最大的数字。

  1. atol() 将字符串转换为长整型值
char *a = "12345.6";num = atol(a);

转换100000次耗时约23毫秒,转换的数字越大,耗时越长。
其他性质和atoi类似。

  1. atof() 将字符串转换为双精度浮点型值
char *a = "12345.6";num = atol(a);

转换100000次耗时约90毫秒,转换的数字越大,耗时越长。
当输入的数字超过一个小数点时,忽略第二个小数点前的部分,当输入的内容包含非法字符时,输出该字符前的部分,当输入的数字从第一个字符开始不合法时,输出0,认可“.8”这种表示方式,会输出0.8,但是如果输入“-0.a”会输出-0,但是判断它是否小于0时,编译器的反馈是否,判断它是否等于0时, 编译器的反馈是是

  1. strtod() 将字符串转换为双精度浮点型值,并报告不能被转换的所有剩余数字
char *a = "12345.6";char *leftover;num = strtod(a,&leftover);

转换100000次耗时约95毫秒,转换的数字越大,耗时越长。
总得来说和atof()差不多,不同之处在于,会把不能转换的部分保存在strtod()的第二个参数,leftover所指向的字符串中。

  1. strtol() 将字符串转换为长整值,并报告不能被转换的所有剩余数字
char *a = "12345.6";char *leftover;num = strtol(a,&leftover,10);

转换100000次耗时约20毫秒,转换的数字越大,耗时越长。
strtol()要接收三个参数,最后一个是进制。总得来说和atol()差不多,会把不能转换的部分保存在strtol()的第二个参数,leftover所指向的字符串中。
可以读取十六进制,十六进制中的“a”和“A”都是认的,0x前缀加不加都一样,函数认为这是一个合法的前缀。

  1. strtoul() 将字符串转换为无符号长整型值,并报告不能被转换的所有剩余数字
char *a = "12345.6";char *leftover;num = strtoul(a,&leftover,10);

转换100000次耗时约20毫秒,转换的数字越大,耗时越长。
总得来说和strtoul()差不多。
当输入的是负数时,并不会表示该数非法,而是当它是一个无符号长整型处理。

  1. _itoa_s() 将整型转换为指定进制的字符串存放在字符串数组中(字符为char类型)
double num = 12345.6;char a[100];_itoa_s(num,a,100,10);

是_itoa()的安全版本,第二个参数必须是指定好范围的char*或是char数组名。第三个参数是存放转换结果的字符串长度,第四个参数是基数。
转换100000次耗时约9毫秒,转换的数字越大,耗时越长。
那些所谓非法字符的情况是不太可能出现的,因为在赋值的时候就会出问题,送入函数的一般是合法的整型数字。

  1. _itow_s() 将整型转换为指定进制的宽字符串存放在宽字符串数组中(字符为wchar_t类型,根据环境不同占两个字节或四个字节)
double num = 12345.6;wchar_t a[100];_itoa_s(num,a,100,10);

是_itow()的安全版本,第二个参数必须是指定好范围的wchar_t*或是wchar_t数组名。第三个参数是存放转换结果的宽字符串长度,第四个参数是基数。
转换100000次耗时约9毫秒,转换的数字越大,耗时越长。
和_itoa_s()差不多,但是由于是wchar_t 类型,cout的时候看起来会不太一样,设断点看数组中的内容是没有问题的。

二、sscanf()和sprintf()
参考资料
http://www.cnblogs.com/Anker/p/3351168.html
头文件:#include <stdio.h>

  1. sscanf() 字符串转数字
    功能包括:
    (1)根据格式从字符串中提取数据。如从字符串中取出整数、浮点数和字符串等。
    (2)取指定长度的字符串
    (3)取到指定字符为止的字符串
    (4)取仅包含指定字符集的字符串
    (5)取到指定字符集为止的字符串
int num;char a[100]=“12345.6”;sscanf_s(a,"%d",&num);

转换100000次耗时约75毫秒,转换的数字越大,耗时越长。
第一个参数可以是数组名也可以是设定好范围的char*指针。
其实掌握了scanf也就掌握了sscanf_s,两者有很多共同之处,这里不再赘述。

  1. sprintf()_s 数字转字符串
    功能包括:
    (1)将数字变量转换为字符串。
    (2)得到整型变量的16进制和8进制字符串。
    (3)连接多个字符串。
int num = 12345.6;char a[100];sprintf_s(a,"0x%X",num);

第一个参数只接受数组名,不接受指针。
转换100000次耗时约40毫秒,转换的数字越大,耗时越长。
连接字符串的方法为:`sprintf_s(str,”%s %s”,s1,s2);

三、输入输出流
参考资料
http://blog.csdn.net/lichengiggs/article/details/722867
http://blog.csdn.net/yang3wei/article/details/25693695
头文件:#include<sstream>
这里其实只要把流当成cin和cout一样就好了。

string a="12345.6";stringstream ss;//ss << "222222222222222222";ss << a;ss >> num;

转换100000次耗时约47毫秒,转换的数字越大,耗时越长。
但是在这里如果添加上注释掉的那一行,得到的就不会是我们期望的结果,这是由于流中的内容没有清空造成的。清空流的方法是:用clear方法清空流的状态,再用.str(“”)方法清空流的内容

ss.clear();ss.str("");

实际使用时,如果要重复使用一个流,显然每次使用都要清空流,那么将清空语句放在循环体内比较更加公平。这时花费时间暴增,转换100000次耗时约850毫秒。因此,真正投入实际使用时,虽然输入输出流是一种很方便的互转方式,但是在时间上代价比较大。

总结:
上述一、二、三中,花费时间从短到长依次为一,二,三。
在不需要清空流的情形下,二和三的耗时差不多。

0 0
原创粉丝点击