C++基础(六)字符串与数字互转

字符串转换成数字

常见的有三种方法:

1、利用C语言的函数atoi、atof等;

2、利用C++的流,std::stringstream;

3、利用std::stoi、std::stod等函数。

各有优劣,下面逐一分析。

为了方便,将std::stringstream的方法封装成一个模板函数,如下:

template<typename out_type, typename in_value>
out_type convert(const in_value & t){
	std::stringstream stream;
	stream << t;
	out_type result;
	stream >> result;
	return result;
}

测试代码如下:

int _tmain(int argc, _TCHAR* argv[])
{	
	auto funPrint = [](const std::string& str){
		std::cout << "-------------------------------------------" << std::endl;
		std::cout << "原始字符串:" << str << std::endl;
		std::cout << "aotf:" << atof(str.c_str()) << std::endl;
		std::cout << "convert:" << convert<double>(str) << std::endl;
		std::cout << "std::stod:" << std::stod(str) << std::endl;
	};
	std::string strValue("12.4ds52");
	funPrint(strValue);
	system("pause");
	return 0;
}

这里为了后面的测试,将打印功能封装成了一个lambda表达式,执行结果如下:

三种方法,似乎没有区别,都是遇到第一个非合法字符就停止转换。继续,将主函数修改如下:

int _tmain(int argc, _TCHAR* argv[])
{	
	auto funPrint = [](const std::string& str){
		std::cout << "-------------------------------------------" << std::endl;
		std::cout << "原始字符串:" << str << std::endl;
		std::cout << "aotf:" << atof(str.c_str()) << std::endl;
		std::cout << "convert:" << convert<double>(str) << std::endl;
		std::cout << "std::stod:" << std::stod(str) << std::endl;
	};
	std::string strValue("12.4ds52");
	funPrint(strValue);
	strValue = ("a23.4ds52");
	funPrint(strValue);
	system("pause");
	return 0;
}

与上面相比,多了一次给strValue重新赋值,新的值第一个字符就是非数字,执行结果如下:

很不幸,程序崩溃!!!

从执行结果可以看出来,崩溃的乃是std::stod(str)这一句;另外,利用std::stringstream转换得到的数字为一个未初始化的双精度浮点数;似乎只有atof执行得比较靠谱。

std::stod系列函数(std::stoi、std::stof等),是可以避免让其崩溃的。当给定的字符串完全不能转换成数字,就会抛出一个std::invalid_argument的异常。据此,不但能避免崩溃,一定程度上还能判断字符串的合法性。修改代码如下:

int _tmain(int argc, _TCHAR* argv[])
{	
	auto funPrint = [](const std::string& str){
		std::cout << "-------------------------------------------" << std::endl;
		std::cout << "原始字符串:" << str << std::endl;
		std::cout << "aotf:" << atof(str.c_str()) << std::endl;
		std::cout << "convert:" << convert<double>(str) << std::endl;
		try
		{
			std::cout << "std::stod:" << std::stod(str) << std::endl;
		}
		catch (std::invalid_argument&)
		{
			std::cout << "非法字符串!" << std::endl;
		}		
	};
	std::string strValue("12.4ds52");
	funPrint(strValue);

	strValue = ("a23.4ds52");
	funPrint(strValue);

	strValue = ("-.23.124.512");
	funPrint(strValue);

	strValue = ("--1.124");
	funPrint(strValue);
	system("pause");
	return 0;
}

执行结果如下:

可以看到,四个字符串严格来说,都是非法的,但是只有第二个和第四个抛出了异常。

所以在实际项目中,需要根据具体情况,进行一些异常处理和判断,再选择合适的方式进行转换。

数字转换成字符串

与字符串转成数字差不多,也有三种方式:

1、sprintf_s函数(需要加上头文件 #include "stdio.h");

2、利用std::stringstream流;

3、std::to_string函数(宽字符可用std::to_wstring);

利用std::stringstream流,就是上面封装的convert函数。

sprintf_s函数为sprintf函数的安全版本,需要指定缓冲区大小。

示例代码如下:

int _tmain(int argc, _TCHAR* argv[])
{    
    auto funPrint_dTos = [](double dValue){
        std::cout << "-------------------------------------------" << std::endl;
        std::cout << "原始数字:" << dValue << std::endl;
        char arr[216];
        sprintf_s(arr, 216, "%f", dValue);
        std::cout << "sprintf_s:" << arr << std::endl;
        std::cout << "convert:" << convert<std::string>(dValue) << std::endl;
        std::cout << "std::to_string:" << std::to_string(dValue) << std::endl;
    };
    funPrint_dTos(12.563);
    system("pause");
    return 0;
}

执行结果如下:

可以看到,sprintf_s和std::to_string都会保留精度,不够的会在小数末尾加上0。当然,sprintf_s可以指定保留的小数位数,将上述代码中的 sprintf_s(arr, 216, "%f", dValue)改为sprintf_s(arr, 216, "%.2f", dValue),执行结果如下:

至于std::to_string,似乎没有指定保留小数位数的办法,只能根据需求自己封装一个函数。

std::stringstream可以自动精确,去除末尾的0。

同样,也需要根据需求选择转换方式。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值