C++使用stringstream进行数据类型转换

(参阅:http://www.cppblog.com/sandywin/archive/2007/07/13/27984.html)
在写程序的过程中,我们经常需要进行数据类型的转换,也经常搞混。但是如果使用stringstream的话,就在也不用担心了。

sstream

stringstream在头文件中,库定义了三种类:istringstreamostringstreamstringstream,分别用来进行流的输入、输出和输入输出操作。

使用stringstream进行转换,比C的sprintf等更安全,不用担心输错格式化符号(如%d,%f等)也更方便。

直接转换

最简单的:

    int n;
    stringstream ss;
    ss << s;                //ss = "12345"
    ss >> n;                //n = 12345

或者stringchar *

    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(""),直接将其设置为空串就好

你可能感兴趣的:(C/C++)