字符串流直接和内存打交道的,而不是文件或标准输入输出。如果你想建立一个字符串流并从中提取数据,用istringstream对象;如果是
想把字符串插入到一个字符串流中,用Ostringstream对象。字符串流的所有声明包含在标准头文件<sstream>中。照样的,这个模板类也是继承自iostream;
(一)Input string streams
要从一个字符串中用字符串流操作读取数据,可以先创建一个istringstream对象并用那个字符串初始化。下面的例子展示了如何应用istringstream类:
//:C04:Istring.cpp
//Input string streams
#include <cassert>
#include <math> //For fabs()
#include <iostream>
#include <limits> //For epsilon()
#include <sstream>
#include <string>
int main(){
istringstream s("47 1.414 This is a test");
int i;
double f;
s>>i>>f;//Whitespace-delimited input
assert(i==47);
double relerr =(fabs(f) - 1.414)/1.414;
assert(relerr<=numeric_limits<double>::epsilon());
string buf2;
s>>buf2;
assert(buf2=="This");
cout<<s.rdbuf(); //" is a test"
}///:~
看到了吗,不要以为只有c语言中的atof()或atoi()可以将字符串转换成数据类型,上面的方法更为灵活和普遍,即使是单个字符的转换!
在s>>i>>f里,字符串中的第一个数提取给了i,第二个给了f。这并不是由空格作为首选定限字符决定的,而是取决于被提取的数据的类型(若类型不符则不赋值,继续向前读取)!例如,如果原字符串为"1.414 47 This is a test",那么i将会被赋值为1,f将会被赋值为0.414。如果你想把一个浮点数分割成一个整数和一个小数,这未免不是一种非常好的方法^_^。第二个assert()中注意用来判断浮点数是否相等的方法。定义于<limits>中的epsilon(),返回一个常量值,表示两个双精度数据的机器误差,在比较双精度数时足够小的令我们满意的,故请放心使用。
或许你已经猜测到了,buf2没有获得余下的字符串,而是下一个空格符前的字符串。一般的,如果你知道要提取的数据序列并且要转换成其他类型而不是字符串是,最好使用提取符(>>)。但是,如果你想一次提取剩下的字符串并放到另一个流中,那就用rdbuf()吧。
(二)Output string streams
创建一个输出字符串流,我们用到Ostringstreams对象。它管理着一个动态大小的内存块,存放着你要插入的随便什么类型的数据。若要将数据格式化成字符串,可以调用它的str()成员函数。下面是一个例子:
//:C04:Ostring.cpp
//Illustrates ostringstream
#include <iostream>
#include <sstream>
#include <string>
#using namespace std;
int main()
{
cout<<"type an int,a float and a string";
int i;
float f;
cin>>i>>f;
cin>>ws;
//Throw away white space
string stuff;
getline(cin,stufff); //Get rest of the line
ostringtream os;
os<<"integer="<<i<<endl;
os<<"float="<<f<<endl;
os<<"string="<<stuff<<endl;
string result=os.str();
cout<<result<<endl;
}
和前面的Istring.cpp的例子差不多,都是取一个整数和浮点数。执行结果如下:
type an int,a float and a string:10 20.5 the end
integer=10
flaot=20.5
string=the end
(以上为cout<<result<<endl;的输出,os只是输入到内存中,并不输出到屏幕上)
你可以看到,和其他的输出流一样,你可以使用一般的格式化工具,比如<<操作符和endl发送数据到ostringstream.str()函数每次调用返回一个新的string对象,这样存在于string缓冲区中的对象就不会被破坏。
os.seekp(8,ios::beg);移动输出指针到开始第8个字符处
os.seekp(8,ios::cur);移动输入指针从当前位置开始第8个字符处