istringstream
istringstream提供了一个类似输入流一样的处理字符串的输入流。它可以绑定一个字符串,然后用空格将它们分割开来。它有两个构造函数,通常使用第一个:
explicit istringstream ( openmode which = ios_base::in ); explicit istringstream ( const string & str, openmode which = ios_base::in)
第二个构造参数可以有6个候选,但是我不知都是些啥意思,悲剧啊。使用方法可以用下面的小例子说明:
void testIss() { string s = "Something in the way she moves"; string tmp; istringstream iss(s, istringstream::in); for (istream_iterator<string> iter(iss); iter != istream_iterator<string>();iter++) cout << iter->c_str() << endl; }
实际上就是把s看成了类似cin的输入,然后按照空格和回车符号分割成各个单词。当然不仅限于如此,下面是另外的一个例子
void testIss_2() { int n, val; string stringvalues; stringvalues = "125 320 512 750 333"; istringstream iss(stringvalues, istringstream::in); for (n = 0; n < 5; n++) { iss >> val; cout << val * 2 << endl; } }
怎么样,够简单吧。istringstream中有一些get,getline等方法,这和cin流中的方法一致,是从绑定的string读入一个和一行字符。
ostringstream
ostringstream和istringstream相似,它是一个按流方式处理字符串的输出流。它也有两个构造函数,通常用第二种:
explicitostringstream ( openmode which = ios_base::out );
explicit ostringstream ( const string & str, openmode which = ios_base::out);
C++Reference上面给出了一个简单的例子:
void testOss_1() { ostringstream oss (ostringstream::out); oss << "This is a test\n"; cout << oss.str(); return ; }
这个例子给出了利用ostringstream构造一个简单字符串。实际上oss使用方法和cout一样(实际上cout是ostream的一个实例,oss是ostringstream的一个实例,而ostringstream是从ostream中继承而来的)。
实际中ostringstream通常用于替代sprintf和CString.Format()来构造字符串。例如:sprintf(buf,"this is a string : %s , %s", str);这存在两个问题,第一,如果buf的空间不够大,而str的长度又十分长,拼接之后的结果会丢失超过buf空间的字符;第二,第一个%s用str替换,第二个%s用什么替代呢,这是个明显的错误,但是编译器无法检测出来,不同的编译器会给出不同的结果,我的测试程序是:
void testsprintf() { char buf[100] = {0}; const char *str = "string"; sprintf(buf,"this is a string : %s , %s", str); printf("%s", buf); return ; }
mingw-g++的结果是:this is a string : string , this is astring : string ,
msvc10的结果是:this is a string : string ,T?(每次的结果都不一样)
同样的CString也存在上面两个问题,而且CString在设计时考虑到效率问题,内存是重复利用的,即:一个进程中所有的CString对象都使用同一个内存缓冲区,且这个内存区运行时不会释放,直到进程结束为止。如果缓冲不够,他会无限制往上增长.如果你设计的系统是一个7*24运行的系统且字符串分析工作量很大,程序中产生了大量的CString对象的话,你可能会发现你的内存会不断的上涨。string同样有一个很优秀且高效率的内存管理机制,但他不会死守着你的内存不放,这一点你看看STL的源码就知道了。
stringstream
stringstream顾名思义,实际上是istringstream和ostringstream的结合体,它是从iostream派生而来的。由于stringstream既重载了<<也重载了>>,所以它通常用来代替C风格的字符串到数据的转换工作。例如:
string result="10000"; int n=0; stream<<result; stream>>n;
需要注意的是,如果你打算在多次转换中使用同一个stringstream对象,记住再每次转换前要使用str("")方法(有的文章中指出是clear()方法,但是我查阅C++ Reference上面说clear是从ios继承而来的方法,意义是复位出错状态)。在多次转换中重复使用同一个stringstream(而不是每次都创建一个新的对象)对象最大的好处在于效率。stringstream对象的构造和析构函数通常是非常耗费CPU时间的。