如何记忆 C/C++ 中各类字符串类型之间的转换
懒惰的程序猿怎么能够去记这么多东西呢!最好的办法,就是用最少的记忆!最好是跟标准的输入输出一样的方式,只需要稍微的做一点改动就好!
如果你熟悉printf和scanf,那你可以稍微的,学学sprintf和sscanf,它们的参数跟printf/scanf只多了第一个参数,传入一个char数组。
char str[128];
int i = 12345;
printf("%d", i); //输出一个整数到标准输出流
sprintf(str, "%d", i); //输出一个整数到字符串str
scanf("%d", &i); //从标准输入流读取一个整数到i
sscanf("54321", "%d", &i); //从字符串"54321"读取一个整数到i
其他类型同理。
如果你熟悉cout和cin,那你可以稍微的学学stringstream,它们用起来跟cin和cout几乎一毛一样!
//需要 #include<sstream>
string str;
int i = 12345;
cout<<i; //输出一个整数到标准输出流
ostringstream strout; //定义一个字符串输出流
strout<<i; //输出一个整数到字符串输出流
str = strout.str(); //获取字符串输出流的内容
cin>>i; //从标准输入流读取一个整数到i
istringstream strin("54321"); //定义一个字符串输入流
strin>>i; //从字符串输入流读取一个整数到i
其他类型同理。
当然,作为懒惰的程序猿,如果学会了模板,我们还可以更懒!因为我们可以把它们封装成一个头文件,以后用它就好了,而且,代码少之又少!
// strutils.h
#ifndef STR_UTILS_H
#define STR_UTILS_H
#include <sstream>
#include <string>
using namespace std;
/*
把一个变量转为字符串,适用于能够直接cout输出的类型!
用法举例:
string strInt = toString(123);
string strDouble = toString(123.4);
string strPointer = toString(&strInt);
*/
template<typename T>
string toString(T t) {
ostringstream strout;
strout << t;
return strout.str();
}
/*
字符串转变量,适用于可以用cin输入的类型!
用法举例:
int i;
fromString("123", i);
double d;
fromString("123.4", d);
*/
template<typename T>
void fromString(const string& str, T& t) {
istringstream(str);
str >> t;
}
/*
字符串转变量的另一种形式,适用于可以用cin输入的类型!
用法举例:
int i = fromString<int>("123");
double d = fromString<double>("123.4");
*/
template<typename T>
T fromString(const string& str) {
T t;
istringstream(str);
str >> t;
return t;
}
#endif
以上。
sprintf/sscanf是c/c++通用的,代码少,效率也不低,如果能记住printf/scanf的参数的话,sprintf/sscanf是很容易学会的(不,其实基本上不用学吧)。
stringstream是c++特有的。代码看起来稍微多一些,而且每次转换都需要创建一个stringstream对象。优点是跟cin/cout一样,可以接受多种类型的变量,用模板一封装,用起来可读性好,而且实现起来代码也不多!缺点就是每次都创建stringstream对象,而且toString还需要按值返回,部分编译器可能造成复制导致效率更低。综合考虑效率可能比sprintf/sscanf稍微低一些。
---我是分割线---
话说我对效率的分析就是闭着眼睛拍脑袋说的,并没有数据支撑,也许sprintf/sscanf解析参数%d %f啥的,运行效率可能也不如作为模板类的stringstream。总之,挑一个你觉得学起来容易并且不容易忘记的吧!
2017-08-17
~
~
~