当>>时改变双引号的行为一个字符串流

时间:2011-01-15 19:02:48

标签: c++ stl stringstream

这是我正在尝试做的事情:

说我有一个字符串流。然后我<< "\"hello world\" today";

然后当我做

sstr >> myString1 >> myString2;

我希望myString1拥有“你好世界” 并为myString2拥有“今天”

有没有办法,可能还有操纵者来实现这个目标?

由于

7 个答案:

答案 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"
  • 跳过领先的空白?
    • 与getline不同,尊重流的skipws标志是有道理的,但我可以看到在极少数情况下会以另一种方式出现
    • istream sentry会为你处理这个
  • 不要忘记使用流的特征和区域设置,或使用已经这样做的方法!
    • 或记录您的假设

答案 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]

*来源:https://en.cppreference.com/w/cpp/io/manip/quoted