【本文来自】http://www.builder.com.cn/2003/0304/83250.shtml
http://www.cppblog.com/alantop/archive/2007/07/10/27823.html
使用stringstream对象简化类型转换
C++标准库中的
为什么要学习
如果你已习惯了
int n=10000;
chars[10];
sprintf(s,”%d”,n);// s中的内容为“10000”
到目前为止看起来还不错。但是,对上面代码的一个微小的改变就会使程序崩溃:
int n=10000;
char s[10];
sprintf(s,”%f”,n);// 看!错误的格式化符
在这种情况下,程序员错误地使用了%f格式化符来替代了%d。因此,s在调用完sprintf()后包含了一个不确定的字符串。要是能自动推导出正确的类型,那不是更好吗?
进入stringstream
由于n和s的类型在编译期就确定了,所以编译器拥有足够的信息来判断需要哪些转换。
注意,
string result=”10000”;
int n=0;
stream<
重复利用stringstream对象
如果你打算在多次转换中使用同一个stringstream对象,记住再每次转换前要使用clear()方法;
在多次转换中重复使用同一个stringstream(而不是每次都创建一个新的对象)对象最大的好处在于效率。stringstream对象的构造和析构函数通常是非常耗费CPU时间的。
在类型转换中使用模板
你可以轻松地定义函数模板来将一个任意的类型转换到特定的目标类型。例如,需要将各种数字值,如int、long、double等等转换成字符串,要使用以一个string类型和一个任意值t为参数的to_string()函数。to_string()函数将t转换为字符串并写入result中。使用str()成员函数来获取流内部缓冲的一份拷贝:
template
void to_string(string & result,const T& t)
{
ostringstream oss;//创建一个流
oss<
result=oss.str();//获取转换后的字符转并将其写入result
}
这样,你就可以轻松地将多种数值转换成字符串了:
to_string(s1,10.5);//double到string
to_string(s2,123);//int到string
to_string(s3,true);//bool到string
可以更进一步定义一个通用的转换模板,用于任意类型之间的转换。函数模板convert()含有两个模板参数out_type和in_value,功能是将in_value值转换成out_type类型:
template
out_type convert(const in_value & t)
{
stringstream stream;
stream<
out_type result;//这里存储转换结果
stream>>result;//向result中写入值
return result;
}
这样使用convert():
double d;
string salary;
string s=”12.56”;
d=convert
salary=convert
结论
在过去留下来的程序代码和纯粹的C程序中,传统的
一些实例:
stringstream通常是用来做数据转换的。
相比c库的转换,它更加安全,自动和直接。
例子一:基本数据类型转换例子 int转string
#include
#include
#include
int main()
{
std::stringstream stream;
std::string result;
int i = 1000;
stream << i; //将int输入流
stream >> result; //从stream中抽取前面插入的int值
std::cout << result << std::endl; // print the string "1000"
}
例子二:除了基本类型的转换,也支持char *的转换。
#include
#include
int main()
{
std::stringstream stream;
char result[8] ;
stream << 8888; //向stream中插入8888
stream >> result; //抽取stream中的值到result
std::cout << result << std::endl; // 屏幕显示 "8888"
}
例子三:再进行多次转换的时候,必须调用stringstream的成员函数clear().
#include
#include
int main()
{
std::stringstream stream;
int first, second;
stream<< "456"; //插入字符串
stream >> first; //转换成int
std::cout << first << std::endl;
stream.clear(); //在进行多次转换前,必须清除stream
stream << true; //插入bool值
stream >> second; //提取出int
std::cout << second << std::endl;
}
一、简单介绍
ostringstream是C++的一个字符集操作模板类,定义在sstream.h头文件中。ostringstream类通常用于执行C风格的串流的输出操作,格式化字符串,避免申请大量的缓冲区,替代sprintf。
派生关系图:
二、ostringstream的基本使用
explicit ostringstream ( openmode which = ios_base::out );
有时候,我们需要格式化一个字符串,但通常并不知道需要多大的缓冲区。为了保险常常申请大量的缓冲区以防止缓冲区过小造成字符串无法全部存储。这时我们可以考虑使用ostringstream类,该类能够根据内容自动分配内存,并且其对内存的管理也是相当的到位。取得std::ostringstream里的内容可以通过str()和str(string&)成员函数。
三、注意事项
std::ostringstream::str()返回的是临时对象,不能对其直接操作。
例如会有如下误用:
const char * pBuffer = oss.str().c_str();
注意pBuffer指向的内存已被析构!!
四、代码测试
- #include
- #include
- #include
- using namespace std;
- void main()
- {
- ostringstream ostr1; // 构造方式1
- ostringstream ostr2("abc"); // 构造方式2
- /*----------------------------------------------------------------------------
- *** 方法str()将缓冲区的内容复制到一个string对象中,并返回
- ----------------------------------------------------------------------------*/
- ostr1 << "ostr1 " << 2012 << endl; // 格式化,此处endl也将格式化进ostr1中
- cout << ostr1.str();
- /*----------------------------------------------------------------------------
- *** 建议:在用put()方法时,先查看当前put pointer的值,防止误写
- ----------------------------------------------------------------------------*/
- long curPos = ostr2.tellp(); //返回当前插入的索引位置(即put pointer的值),从0开始
- cout << "curPos = " << curPos << endl;
- ostr2.seekp(2); // 手动设置put pointer的值
- ostr2.put('g'); // 在put pointer的位置上写入'g',并将put pointer指向下一个字符位置
- cout << ostr2.str() << endl;
- /*----------------------------------------------------------------------------
- *** 重复使用同一个ostringstream对象时,建议:
- *** 1:调用clear()清除当前错误控制状态,其原型为 void clear (iostate state=goodbit);
- *** 2:调用str("")将缓冲区清零,清除脏数据
- ----------------------------------------------------------------------------*/
- ostr2.clear();
- ostr2.str("");
- cout << ostr2.str() << endl;
- ostr2.str("_def");
- cout << ostr2.str() << endl;
- ostr2 << "gggghh"; // 覆盖原有的数据,并自动增加缓冲区
- cout << ostr2.str() << endl;
- ostr2.str(""); // 若不加这句则运行时错误,因为_df所用空间小于gggghh,导致读取脏数据
- ostr2.str("_df");
- cout << ostr2.str() << endl;
- // 输出随机内存值,危险
- const char* buf = ostr2.str().c_str();
- cout << buf << endl;
- // 正确输出_df
- string ss = ostr2.str();
- const char *buffer = ss.c_str();
- cout << buffer << endl;
- }
#include
#include
#include
using namespace std;
void main()
{
ostringstream ostr1; // 构造方式1
ostringstream ostr2("abc"); // 构造方式2
/*----------------------------------------------------------------------------
*** 方法str()将缓冲区的内容复制到一个string对象中,并返回
----------------------------------------------------------------------------*/
ostr1 << "ostr1 " << 2012 << endl; // 格式化,此处endl也将格式化进ostr1中
cout << ostr1.str();
/*----------------------------------------------------------------------------
*** 建议:在用put()方法时,先查看当前put pointer的值,防止误写
----------------------------------------------------------------------------*/
long curPos = ostr2.tellp(); //返回当前插入的索引位置(即put pointer的值),从0开始
cout << "curPos = " << curPos << endl;
ostr2.seekp(2); // 手动设置put pointer的值
ostr2.put('g'); // 在put pointer的位置上写入'g',并将put pointer指向下一个字符位置
cout << ostr2.str() << endl;
/*----------------------------------------------------------------------------
*** 重复使用同一个ostringstream对象时,建议:
*** 1:调用clear()清除当前错误控制状态,其原型为 void clear (iostate state=goodbit);
*** 2:调用str("")将缓冲区清零,清除脏数据
----------------------------------------------------------------------------*/
ostr2.clear();
ostr2.str("");
cout << ostr2.str() << endl;
ostr2.str("_def");
cout << ostr2.str() << endl;
ostr2 << "gggghh"; // 覆盖原有的数据,并自动增加缓冲区
cout << ostr2.str() << endl;
ostr2.str(""); // 若不加这句则运行时错误,因为_df所用空间小于gggghh,导致读取脏数据
ostr2.str("_df");
cout << ostr2.str() << endl;
// 输出随机内存值,危险
const char* buf = ostr2.str().c_str();
cout << buf << endl;
// 正确输出_df
string ss = ostr2.str();
const char *buffer = ss.c_str();
cout << buffer << endl;
}
运行结果如下:
http://blog.csdn.net/lanxuezaipiao/article/details/16358159