C ++ 14逐字提取引用的字符串,包括引号

时间:2016-11-14 14:40:56

标签: c++ string c++14 stringstream

让我有一个字符串:

string tstring = "Some arbitrarily long string which has \"double quotes\" which has to be printed verbatim";

我尝试使用stringstreams并引用来提取单词

stringstream stream(tstring);
string tepm;
while(stream >> std::quoted(temp))
    cout << temp << endl;

但是上面的内容会跳过引用字符串

中的引号
Some
arbitrarily
.
.
double quotes
.
.
verbatim

我希望所引用的字符串逐字打印,并带有引号

Some
arbitrarily
.
.
"double quotes"
.
.
verbatim

我如何使用引用函数执行此操作,或者如果不可能有更好的方法(除了当然逐字逐句阅读并自己完成所有工作)

修改

这是根据要求提供的MCVE

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>

using namespace std;

int main(){
    string sspace = "Hi this is \"Real Madrid\"";
    stringstream stream(sspace);
    string fpart;
    while(stream >> quoted(fpart)){
        cout << fpart << endl;
    }
    return 0;
}

2 个答案:

答案 0 :(得分:2)

在输入中使用时,std::quoted会从字符串中删除未转义的引号并取消转义转义引号。所以像这样的字符串:

"some \"string with\" inner quotes"
读入时

成为了这个:

some "string with" inner quotes

但为了实现这一点,必须在流中引用和转义字符串。如果你这样做:

std::string str = "string \"with some\" quotes";
std::stringstream ss (str);
std::cout << "stream contents: " << ss.str() << std::endl;

流内容实际上是:

string "with some" quotes

当声明str并未在流中结束时,您正在逃避,只有解析器才会出现这种情况。如果你希望它的编写方式与输出流中的完全相同,那么你必须这样写:

std::string str = "\"string \\\"with some\\\" quotes\"";

或更好:

std::string str = "string \"with some\" quotes";
ss << std::quoted(str);

并离开std::quoted完成它的工作。

答案 1 :(得分:2)

我不认为std::quoted是这里工作的正确工具,因为没有简单的方法可以判断下一个字符串是否有在打印之前被剥离的引号(它丢弃了)您的分隔符,默认为'\"'

我认为我们可以放心使用std::string的{​​{1}}方法。

  • 包含一个子程序,用于打印不在引号内的所有单词(空格分隔)
  • 继续阅读,直到下一个引用字符利用find

完整代码:

find

Live Demo

如果您需要将引用的字符存储在变量中,则行

void PrintUnquoted(std::string _in)
{
    std::istringstream ss(_in);
    std::string temp;
    while(ss >> temp)
    {
        std::cout << temp << '\n';
    }
}

int main(){
    std::string sspace = "Hi this is \"Real Madrid\" etc.";
    size_t start = 0;
    size_t nextQuote = 0;
    while(nextQuote = sspace.find('\"', start), nextQuote != std::string::npos)
    {
        size_t endQuote = sspace.find('\"', nextQuote+1);
        if (endQuote == std::string::npos)
        {
            throw std::logic_error("Unmatched quotes");
        }

        PrintUnquoted(sspace.substr(start, nextQuote-start));
        std::cout << sspace.substr(nextQuote, endQuote-nextQuote+1) << std::endl;
        start = endQuote+1;
    }
    if (start < sspace.size())
    {
        PrintUnquoted(sspace.substr(start));
    }
    return 0;
}

应该很容易修改以获得它。