这是我正在尝试做的事情:
说我有一个字符串流。然后我<< "\"hello world\" today";
然后当我做
sstr >> myString1 >> myString2;
我希望myString1拥有“你好世界” 并为myString2拥有“今天”
有没有办法,可能还有操纵者来实现这个目标?
由于
答案 0 :(得分:5)
简答:否
长答案:
没有任何操作可以帮助你。
替代答案:
您可以编写自己的类型,可以与流操作符一起使用来执行此任务。
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
class QuotedWord
{
public:
operator std::string const& () const { return data;}
private:
std::string data;
friend std::ostream& operator<<(std::ostream& str, QuotedWord const& value);
{
return str << value.data;
}
friend std::istream& operator>>(std::istream& str, QuotedWord& value);
{
char x;
str >> x;
if ((str) && (x == '"'))
{
std::string extra;
std::getline(str, extra, '"');
value.data = std::string("\"").append(extra).append("\"");
}
else
{
str.putback(x);
str >> value.data;
}
return str;
}
};
然后它可以正常使用。
int main()
{
QuotedWord word;
std::cin >> word;
std::cout << word << "\n";
// Easily convertible to string
std::string tmp = word;
std::cout << tmp << "\n"
// because it converts to a string easily it can be used where string is needed.
std::vector<std::string> data;
std::copy(std::istream_iterator<QuotedWord>(std::cin),
std::istream_iterator<QuotedWord>(),
// Notice we are using a vector of string here.
std::back_inserter(data)
);
}
> ./a.out
"This is" a test // Input
"This is" // Output
"This is"
答案 1 :(得分:4)
没有
您需要更改流类型(以及解析语义)或使用您自己的字符串类型(因此更改重载操作中的解析语义&gt;&gt;)。
相反,考虑编写一个类似于getline的函数,该函数从流中解析一个可能引用的“单词”:
getqword(sstr, myString1);
getqword(sstr, myString2);
if (sstr) { /* both succeeded */ }
请注意,输入到std :: string已经在空格处终止,所以你只需要先处理一个引用的偷看然后处理边缘情况,其中有很多:
"\"hello world\"today"
答案 2 :(得分:2)
不直接,你需要一个“包装”类,它终止你想要它的位置。
struct QuotedStringReader
{
std::string& str;
QuotedStringReader( std::string& s ) : str( s ) {}
};
std::istream operator>>( std::istream&, const QuotedStringReader& qsr );
std::string s, s2;
stream >> QuotedStringReader( s ) << s2;
请注意,这是一个很少见的情况,你将流式传输到const中 - 因为你可以写入内部str,即使它是const,这样我就可以传入一个临时的。
实际上,因为你可能不知道你要读什么,你可以简单地称它为“TokenReader”,它读取你定义的任何“令牌”。
答案 3 :(得分:1)
不。不是那种特殊的方式。您可以为字符串创建“strong typedef”,并设计一个新的运算符&gt;&gt;因为它表现得那样。
答案 4 :(得分:0)
这是不可能的。这是因为如果你查看operator>>
basic_istream
的实现,这实际上是sstr >> myString1
调用的,你会在for
循环中看到这个:
else if (_Ctype_fac.is(_Ctype::space,_Traits::to_char_type(_Meta)))
break;// whitespace, quit
意思是,一旦你获得“空间”,退出。因此,一旦获得空间,就无法继续向myString1
添加字符。
请注意,这是MSVC ++实现,但我确信您将在所有实现中找到相同的内容!
答案 5 :(得分:0)
您可以重载输入流运算符并在其中包含解析语义。
std::istream& operator>>(std::istream& is, std::string& out)
{
char c;
is >> c;
if (c == '\"')
{
std::getline(is, out, '\"');
return is;
}
else
{
is.putback(c);
return std::operator >>(is, out);
}
}
int main()
{
std::istringstream iss("\"hello world\" today");
std::string test;
while (iss >> test)
std::cout << test << std::endl;
}
答案 6 :(得分:0)
在c ++ 14中
#include <iostream>
#include <iomanip>
#include <sstream>
int main()
{
std::stringstream ss;
std::string in = "String with spaces, and embedded \"quotes\" too";
std::string out;
ss << std::quoted(in);
std::cout << "read in [" << in << "]\n"
<< "stored as [" << ss.str() << "]\n";
ss >> std::quoted(out);
std::cout << "written out [" << out << "]\n";
}
输出:
read in [String with spaces, and embedded "quotes" too]
stored as ["String with spaces, and embedded \"quotes\" too"]
written out [String with spaces, and embedded "quotes" too]