【问题标题】:c++ - Replace string with double quotes to a string with double quotesc++ - 将带双引号的字符串替换为带双引号的字符串
【发布时间】:2017-08-21 04:15:51
【问题描述】:

我正在编写这个软件,让我在我的网站上的工作更轻松一些。我只是输入了一个脚本,它会用 span 为我突出显示代码。它正在到达那里,但我有一个问题。 (我目前正在努力突出 UnityC#)

我希望字符串是黄色的,包括双引号,但我现在尝试它的方式会导致无限循环。我知道我对引号做错了什么,但我不知道那是什么。请帮帮我:)

变量original由std::string original ((istreambuf_iterator<char>(currentFile)), istreambuf_iterator<char>());创建,其中currentFile是我加载的脚本

std::size_t pos = 0;
while(original.find("\"", pos) != std::string::npos)
{
    //find the first occurrence of the quote
    std::size_t found = original.find("\"", pos);
    if(found != std::string::npos)
    {
        //save the start position of the string
        std::size_t start_pos = found;
        //save the end position by searching for the next quotation mark
        std::size_t end_pos = original.find_first_of("\"", start_pos+1);
        //Calculate the size of the string
        std::size_t length = end_pos-start_pos;
        //Make a copy of the word without the quotation marks
        std::string originalWord = original.substr(start_pos+1, length-1);
        //Make the new word with span, original word(without the quotation marks) and add quotation marks around the word
        std::string newWord = std::string("<span class='yellow_code'>") + "\"" + originalWord + "\"" + "</span>";
        std::cout<<originalWord<<" : "<<newWord<<std::endl;
        //Replace the string WITH the quotation marks for the newWord
        original.replace(start_pos, length+1, newWord);
        //Set the position to after the string
        pos = end_pos+1;
    }
    else
    {
        pos = found+1;
    }
}

当我运行它时,它将 cout: /dataValues.dat :​​ "/dataValues.dat" 无限。

怎么了?

问候, 丹妮

【问题讨论】:

  • 如果允许使用 C++11,请考虑使用std::regex。它会很容易地为您做到这一点。
  • 我的老教授坚持称他们为“引用字符”。引号是动词,不是名词;-)
  • 你能给我们举个例子吗?
  • @Shravan40 你的例子是什么意思?我给了代码和输出
  • @danivdwerf 他的意思是输入和输出。以便我们验证您的问题

标签: c++ string c++11 replace


【解决方案1】:

你应该std::regex

text = std::regex_replace(text,std::regex("string to be replaced"),"string with it earlier should be replaced");

【讨论】:

  • 我很欣赏这个答案,但另一个实际上给了我一个问题的答案,而不是告诉我使用一些内置的东西。
【解决方案2】:

问题出在这里:pos = end_pos + 1; 可以让你的索引在字符串之前比你的序言短。

让我们看看你的例子会发生什么:

  • 原来originalbla..."/dataValues.dat"...end_pospos + 16
  • 替换后你得到bla...&lt;span class='yellow_code'&gt;"/dataValues.dat"&lt;/span&gt;... end_pos 没有改变,指向黄色的第一个l
  • 在下一次搜索中,您会再次找到相同的引号字符串...

您必须将&lt;span...&gt;&lt;/span&gt; 的长度添加到end_pos 以使其紧跟在&lt;/span&gt; 之后

【讨论】:

    【解决方案3】:

    您没有添加添加到字符串的开始和结束标记的大小。 这是一个如何做到这一点的示例

    std::string start_tag = "<span class='yellow_code'>";
    std::string end_tag = "\"</span>";
    
    std::size_t pos = 0;
    while(original.find("\"", pos) != std::string::npos)
    {
        std::size_t found = original.find("\"", pos);
        if(found != std::string::npos)
        {
            std::size_t start_pos = found;
            std::size_t end_pos = original.find_first_of("\"", start_pos+1);
            if (end_pos == std::string::npos) // If the number of quotation characters is odd you would get undefined behavior
                break;
            std::size_t length = end_pos - start_pos;
            std::string originalWord = original.substr(start_pos+1, length-1);
            std::string newWord = start_tag + "\"" + originalWord + end_tag; // CHANGED: Added the start and end tags as std::string
            std::cout<<originalWord<<" : "<<newWord<<std::endl;
            original.replace(start_pos, length+1, newWord);
            pos = end_pos + start_tag.size() + end_tag.size(); // CHANGED: Added the size of the two tags
        }
    }
    

    更新

    查看posfoundstart_pos 之后,似乎其中两个是多余的。

    std::size_t start_pos = 0;
    while((start_pos = original.find("\"", start_pos)) != std::string::npos)
    {
        std::size_t end_pos = original.find_first_of("\"", start_pos+1);
        if (end_pos == std::string::npos) // If the number of quotation characters is odd you would get undefined behavior
            break;
        std::size_t length = end_pos-start_pos;
        std::string originalWord = original.substr(start_pos+1, length-1);
        std::string newWord = start_tag + "\"" + originalWord + end_tag; // CHANGED: Added the start and end tags as std::string
        std::cout << originalWord << " : " << newWord <<std::endl;
        original.replace(start_pos, length+1, newWord);
        start_pos = end_pos + start_tag.size() + end_tag.size(); // CHANGED: Added the size of the two tags
    }
    

    试试online

    【讨论】:

    • @danivdwerf 查看对您的问题的支持数,很明显您的问题是真实的、切题的和有趣的。所以本质上,并不愚蠢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 2011-07-08
    • 2012-03-12
    • 1970-01-01
    • 2023-03-23
    • 2017-02-26
    相关资源
    最近更新 更多