Stringstream 到底是做什么的?

我从昨天开始学习 C + + ,我用的是这个文档: http://www.cplusplus.com/files/tutorial.pdf(第32页)。我在文档里找到了一个代码,然后运行了一下。我试着输入 Rs 5.5作为价格,一个整数作为数量,结果是0。 我试着输入5.5和6,结果是正确的。

// stringstreams
#include <iostream>
#include <string>
#include <sstream>


using namespace std;


int main ()
{
string mystr;
float price = 0;
int quantity = 0;


cout << "Enter price: ";
getline (cin,mystr);
stringstream(mystr) >> price;
cout << "Enter quantity: ";
getline (cin,mystr);
stringstream(mystr) >> quantity;
cout << "Total price: " << price*quantity << endl;
return 0;
}

Mystring 命令到底是做什么的:

”在本例中,我们从标准输入获取数值 而不是直接从 标准输入,我们从标准输入(cin)得到行到 字符串对象(mystr) ,然后从中提取整数值 将这个字符串转换为 int (数量)类型的变量。”

我的印象是,该函数将采取一个字符串的整数部分,并使用它作为输入。

282210 次浏览

回答这个问题。stringstream基本上允许您像对待 stream一样对待 string对象,并在其上使用所有 stream函数和运算符。

我看到它主要用于格式化输出/输入的优点。

将数字转换为流对象的 c++实现就是一个很好的例子。

可能的例子:

template <class T>
string num2str(const T& num, unsigned int prec = 12) {
string ret;
stringstream ss;
ios_base::fmtflags ff = ss.flags();
ff |= ios_base::floatfield;
ff |= ios_base::fixed;
ss.flags(ff);
ss.precision(prec);
ss << num;
ret = ss.str();
return ret;
};

也许它有点复杂,但它是相当复杂的。您可以创建 stringstream对象 ss,修改其标志,使用 operator<<将一个数字放入其中,然后通过 str()提取它。我想 operator>>可以用。

此外,在这个示例中,string缓冲区是隐藏的,没有显式使用。但是这篇文章太长了,不可能写出每一个可能的方面和用例。

注意: 我可能是从别人那里偷来的,但是我没有注明原作者。

Sometimes it is very convenient to use stringstream to convert between strings and other numerical types. The usage of stringstream is similar to the usage of iostream, so it is not a burden to learn.

Stringstream 既可以用来读取字符串,也可以用来将数据写入字符串。它主要使用字符串缓冲区,但没有真正的 I/O 通道。

字符串流类的基本成员函数是

  • str(),它以字符串类型返回其缓冲区的内容。

  • str(string),它将缓冲区的内容设置为字符串参数。

下面是如何使用字符串流的示例。

ostringstream os;
os << "dec: " << 15 << " hex: " << std::hex << 15 << endl;
cout << os.str() << endl;

结果是 dec: 15 hex: f

istringstream的用法大致相同。

总之,字符串流是实现 像独立的 I/O 设备一样操纵字符串的一种方便的方法。

仅供参考,类之间的继承关系如下:

string stream classes

您输入了一个字母数字和 int,空格用 mystr分隔。

You then tried to convert the first token (blank delimited) into an int.

The first token was RS which failed to convert to int, leaving a zero for myprice, and we all know what zero times anything yields.

When you only entered int values the second time, everything worked as you expected.

是伪造的 RS 导致代码失败。

From C++ Primer:

istringstream类型读取 绳子Ostringstream写入 绳子,而 弦流读取和写入 绳子

我遇到过一些使用 弦流既方便又简洁的情况。

个案1

这是从 one of the solutions这个密码问题。它展示了一个非常合适的案例,其中使用 弦流是高效和简洁的。

假设 ab是用字符串格式表示的复数,我们希望得到 ab相乘的结果也是用字符串格式表示的。守则如下:

string a = "1+2i", b = "1+3i";
istringstream sa(a), sb(b);
ostringstream out;


int ra, ia, rb, ib;
char buff;
// only read integer values to get the real and imaginary part of
// of the original complex number
sa >> ra >> buff >> ia >> buff;
sb >> rb >> buff >> ib >> buff;


out << ra*rb-ia*ib << '+' << ra*ib+ia*rb << 'i';


// final result in string format
string result = out.str()

case 2

它也是从一个 密码问题,需要你简化给定的路径字符串,使用字符串流的解决方案之一是我见过的最优雅的:

string simplifyPath(string path) {
string res, tmp;
vector<string> stk;
stringstream ss(path);
while(getline(ss,tmp,'/')) {
if (tmp == "" or tmp == ".") continue;
if (tmp == ".." and !stk.empty()) stk.pop_back();
else if (tmp != "..") stk.push_back(tmp);
}
for(auto str : stk) res += "/"+str;
return res.empty() ? "/" : res;
}

Without the use of stringstream, it would be difficult to write such concise code.