我正在尝试从昨天开始学习C ++,我正在使用这个文档:http://www.cplusplus.com/files/tutorial.pdf(第32页)。我在文档中找到了一个代码,然后运行它。我尝试输入价格为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)到a的行 字符串对象(mystr),然后我们从中提取整数值 将此字符串转换为int(quantity)类型的变量。“
我的印象是该函数将采用字符串的整数部分并将其用作输入。
(我不知道如何在这里提问。我也是编程的新手) 谢谢。
答案 0 :(得分:147)
有时使用stringstream在字符串和其他数字类型之间进行转换非常方便。 stringstream
的使用与iostream
的使用类似,因此不需要学习。
Stringstreams既可用于读取字符串,也可将数据写入字符串。它主要使用字符串缓冲区,但没有真正的I / O通道。
stringstream类的基本成员函数是
str()
,以字符串类型返回其缓冲区的内容。
str(string)
,它将缓冲区的内容设置为字符串参数。
以下是如何使用字符串流的示例。
ostringstream os;
os << "dec: " << 15 << " hex: " << std::hex << 15 << endl;
cout << os.str() << endl;
结果是dec: 15 hex: f
。
istringstream
或多或少具有相同的用法。
总而言之,stringstream是一种方便的方法来像独立的I / O设备一样操纵字符串。
仅供参考,类之间的继承关系是:
答案 1 :(得分:16)
回答这个问题。 stringstream
基本上允许您将string
对象视为stream
,并在其上使用所有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
缓冲区被隐藏,未显式使用。但是关于每个可能的方面和用例,写一篇文章的时间太长了。
注意:我可能会从SO上的某个人那里偷走它并进行改进,但我没有注明原作者。
答案 2 :(得分:15)
来自 C ++ Primer :
istringstream 类型读取字符串, ostringstream 写入字符串和 stringstream 读取和写入字符串。
我遇到过一些使用 stringstream 既方便又简洁的情况。
one of the solutions来自this leetcode problem。它演示了一个非常合适的情况,其中 stringstream 的使用是高效和简洁的。
假设a
和b
是以字符串格式表示的复数,我们希望以字符串格式获得a
和b
的乘法结果。代码如下:
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()
同样来自leetcode problem要求你简化给定的路径字符串,one of the solutions using stringstream是我见过的最优雅的:
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;
}
如果不使用stringstream,就很难编写这样简洁的代码。
答案 3 :(得分:2)
您在mystr
中输入了一个字母数字和int,空白分隔。
然后,您尝试将第一个令牌(空白分隔)转换为int
。
第一个令牌是RS,无法转换为int
,为myprice留下零,我们都知道任何收益的零倍。
当你第二次只输入int值时,一切都按预期工作。
虚假的RS导致您的代码失败。