(参阅:http://www.cppblog.com/sandywin/archive/2007/07/13/27984.html)
在写程序的过程中,我们经常需要进行数据类型的转换,也经常搞混。但是如果使用stringstream
的话,就在也不用担心了。
stringstream
在头文件
中,
库定义了三种类:istringstream
、ostringstream
和stringstream
,分别用来进行流的输入、输出和输入输出操作。
使用stringstream
进行转换,比C的
的sprintf
等更安全,不用担心输错格式化符号(如%d,%f等)也更方便。
最简单的:
int n;
stringstream ss;
ss << s; //ss = "12345"
ss >> n; //n = 12345
或者string
转char *
:
std::stringstream stream;
char result[8] ;
string s("8888");
stream << s; //向stream中插入8888
stream >> result; //抽取stream中的值到result
还可以利用模板,进行同一类转换:
template<class T>
void to_string(string& result,const T& t)
{
ostringstream oss; //创建一个流
oss << t; //把值传递如流中
result = oss.str(); //获取转换后的字符转并将其写入result
}
然后就可以把基本数据类型都转换为string
了:
to_string(s, 1); //s = 1
to_string(s, 1.1); //s = 1.1
to_string(s, true); //s = 1
再通用一些,可以将输入类型A和输出类型B均用模板代替,会产生更普遍的转换:
template<class out_type,class in_value>
out_type convert(const in_value& t)
{
stringstream stream;
out_type result; //这里存储转换结果
stream << t; //向流中传值
stream >> result; //向result中写入值
return result;
}
进行A到B类型的转换:
double d;
string salary;
string s2 = "12.56";
d = convert<double>(s2); //d = 12.56
salary = convert<string>(9000.0); //salary = "9000"
注意调用模板的时候要把返回值类型写上。
首先有一个理念要搞清楚:无论是istringstream、ostringstream,还是stringstream,他们都是作为临时缓冲区存在的。
比如现在要写一个文件:
ofstream ofile("output.txt");
要求每符合条件时,就往里写一行内容:
ofile << "blablabla" << endl;
这样频繁I/O会很影响效率。如果我们能够把这些符合条件的东西先存起来,最后集中一次性写入文件,一定会快不少。为此,我们可以定义:
ofstream ofile("output.txt");
ostringstream oss;
每当符合条件时,我们先把符合条件的内容写入缓存:
oss << "blablabla" << endl;
最后一次性写入到文件:
ofile << oss.str();
则能大大提高效率。
所以说,这些缓冲区如果我们不手工清零的话,再次往里放东西的时候他们会接着上次的内容往后添加。所以,如果我们要重复使用他们,一定要先清空。
当然,每次使用之前我们都直接新建一个也可以,但是,在多次转换中重复使用同一个stringstream
(而不是每次都创建一个新的对象)对象最大的好处在于效率。stringstream
对象的构造和析构函数通常是非常耗费CPU时间的。
注意对stringstream的清空使用的不是clear(),对clear()
的解释如下:
void clear (iostate state = goodbit);
Set error state flags
Sets a new value for the stream’s internal error state flags.
它是设置标志位的,不是用来清空内容的。
在stringstream
中,有函数str()
,它有两种用法。
用法一:
string str() const;
returns a string object with a copy of the current contents of the stream.
它的作用是将stringstream
的内容以字符串的形式返回,比如上面在举ostringstream
的例子的时候,我们最后写回文件用的就是ofile << oss.str()
。
用法二:
void str (const string& s);
sets s as the contents of the stream, discarding any previous contents.
它的作用是将stringstream
原有的内容抛弃,并设置为s。
所以我们对stringstream
的清空方式为ss.str("")
,直接将其设置为空串就好。