C++ 如何删除以“开始”开头的每一行//&引用;在std::字符串上?

C++ 如何删除以“开始”开头的每一行//&引用;在std::字符串上?,c++,stdstring,C++,Stdstring,我有以下模板std::string std::string myString = R"svg( <svg height={size} width={size}> <rect {...rectProps} x={x0h} y={y0h} /> // <rect {...rectProps} x={x1h} y={y0h} /> <rect {...rectProps} x={x0h} y={y1h} />

我有以下模板std::string

std::string myString = R"svg(
  <svg height={size} width={size}>
    <rect {...rectProps} x={x0h} y={y0h} />
    // <rect {...rectProps} x={x1h} y={y0h} />
    <rect {...rectProps} x={x0h} y={y1h} />
    // <rect {...rectProps} x={x1h} y={y1h} />
  </svg>
)svg";
没有像我预期的那样工作

它肯定不会像你那样工作。 使用的
erase
重载如下所示

string& erase( size_type index = 0, size_type count = npos);
来自CPP参考的过载说明:

删除从索引开始的最小(count,size()-index)字符

因此,通过
svg.erase(0,svg.find(“/”)+1)
真正要做的是删除从索引[0]到[找到的最后一个
'/'的索引]的所有字符

相反,您应该执行以下操作:

  • 在字符串中搜索
    “//”
    ,将此位置命名为A
  • 在字符串中搜索
    '\n'
    ,将此位置命名为B
  • 从字符串中删除间隔[A;B],如果未找到间隔[A;svg.length()],则删除间隔[A;B]
  • 重复此步骤,直到不再有位置A
  • 另外,我建议从结尾搜索,而不是从开头搜索,因为如果一段字符串更接近结尾而不是开头,则更容易删除它

    p.p.s.如果您想完全删除间隔,也请确保使用迭代器,因为删除间隔的
    erase
    的唯一重载是

    iterator erase( const_iterator first, const_iterator last );
    

    最后,这就是我找到的解决办法

    std::string trim(const std::string &str) {
      size_t first = str.find_first_not_of(' ');
      if (std::string::npos == first) {
        return str;
      }
      size_t last = str.find_last_not_of(' ');
      return str.substr(first, (last - first + 1));
    }
    
    bool startsWith(const std::string &input, const std::string &start) {
      return input.find(start) != std::string::npos;
    }
    
    std::string myString = R"svg(
      <svg height={size} width={size}>
        <rect {...rectProps} x={x0h} y={y0h} />
        // <rect {...rectProps} x={x1h} y={y0h} />
        <rect {...rectProps} x={x0h} y={y1h} />
        // <rect {...rectProps} x={x1h} y={y1h} />
      </svg>
    )svg";
    
    std::istringstream stream(myString);
    std::string line;
    std::string myFinalString;
    while (std::getline(stream, trim(line))) {
      if (!startsWith(line, "//")) {
        myFinalString += line + "\n";
      }
    }
    
    std::string trim(const std::string&str){
    大小\u t first=str.find\u first\u not \u of(“”);
    if(std::string::npos==first){
    返回str;
    }
    大小\u t last=str.find\u last\u not \u of(“”);
    返回str.substr(first,(last-first+1));
    }
    bool startsWith(const std::string和input,const std::string和start){
    返回输入。查找(开始)!=std::string::npos;
    }
    std::string myString=R“svg(
    // 
    // 
    )svg”;
    std::istringstream(myString);
    std::字符串行;
    std::字符串myFinalString;
    while(std::getline(stream,trim(line))){
    如果(!startsWith(第,“/”)行){
    myFinalString+=行+“\n”;
    }
    }
    
    最简单的方法是使用正则表达式库:

    #include <iostream>
    #include <regex>
    
    int main()
    {
        std::string myString = R"svg(
        <svg height={size} width={size}>
            <rect {...rectProps} x={x0h} y={y0h} />
            // <rect {...rectProps} x={x1h} y={y0h} />
            <rect {...rectProps} x={x0h} y={y1h} />
            // <rect {...rectProps} x={x1h} y={y1h} />
        </svg>
        )svg";
        
        std::cout << myString << std::endl; //before
        std::string new_string = std::regex_replace(myString, std::regex("\n *//.*\n"), "\n");
        std::cout << new_string << std::endl; //after
    }
    
    基于找到的
    '/'
    的数量使用是很难简单的,例如

        std::string s { "//Some comment" };
        
        if (s.at(0) == '/')
            s.erase (0, s.find_first_not_of ("/"));
    
    您还可以通过在拒绝字符中添加
    “\t”
    来删除
    “/”
    之前的任何前导空格:

        std::string s { "  //Some comment" };
        
        if (s.at(s.find_first_not_of (" \t/") - 1) == '/')
            s.erase (0, s.find_first_not_of (" \t/"));
    
    注意:at()
    需要
    -1
    ,因为它需要一个从零开始的索引,而
    erase()
    需要一个要删除的字符计数)

    然后,要处理
    “//”
    周围的前导空格和尾随空格,您可以
    #包括
    并使用
    isspace(c)
    ,如下所示:

        std::string s { "  //  Some comment" };
        char c = s.at(s.find_first_not_of (" \t/") - 1);
        
        if (c == '/' || isspace (c))
            s.erase (0, s.find_first_not_of (" \t/"));
    

    在所有情况下,
    “一些注释”
    都是结果。

    这里有一个简单的方法来解决这个问题,它永远不会失败。只要拿出一张白纸。用简单明了的英语写下简短的句子,这是一个循序渐进的过程。完成后。我们不会在Stackoverflow上为其他人编写代码。我们总是把这样的问题交给你们的橡皮鸭。在你的橡皮鸭同意你提出的行动计划后,只需把你写下来的东西直接翻译成C++。任务完成了!您可以使用删除空格,并检查
    “//”
    “但未按预期工作”不是有用的注释。更好的办法是说出你得到了什么样的结果以及你会期望什么。还包括可能的错误消息。@ThomasSablik是std::string的类似示例?文件中是否包含“每一行”或是否要直接从源代码中删除行?您的
    startsWith()
    不太正确,当字符串中不在开头有“/”时,将重新计算假阳性。它应该是
    input.find(start)==0
        std::string s { "//Some comment" };
        
        if (s.at(0) == '/')
            s.erase (0, s.find_first_not_of ("/"));
    
        std::string s { "  //Some comment" };
        
        if (s.at(s.find_first_not_of (" \t/") - 1) == '/')
            s.erase (0, s.find_first_not_of (" \t/"));
    
        std::string s { "  //  Some comment" };
        char c = s.at(s.find_first_not_of (" \t/") - 1);
        
        if (c == '/' || isspace (c))
            s.erase (0, s.find_first_not_of (" \t/"));