2017-10-04 83 views
2

好的,所以我正在用C++编写一个家庭作业项目,并且遇到了一个问题,似乎无法找到解决方法。该函数应该在用户定义的分隔符处破坏输入字符串,并将子字符串存储在一个向量中以便稍后访问。我想我得到了基本的解析器,但它不想分割输入的最后部分。C++字符串解析器问题

int main() { 
    string input = "comma-delim-delim&delim-delim"; 
    vector<string> result; 
    vector<char> delims; 
    delims.push_back('-'); 
    delims.push_back('&'); 
    int begin = 0; 

    for (int i = begin; i < input.length(); i++){ 
     for(int j = 0; j < delims.size(); j++){ 
      if(input.at(i) == delims.at(j)){ 
      //Compares chars in delim vector to current char in string, and 
      //creates a substring from the beginning to the current position 
      //minus 1, to account for the current char being a delimiter. 
       string subString = input.substr(begin, (i - begin)); 
       result.push_back(subString); 
       begin = i + 1; 
      } 

上述代码适用于将输入代码分割到最后一个破折号。之后的任何事情,因为它不会运行到另一个分隔符,它不会保存为一个子字符串,并推入结果向量。所以,试图纠正这个问题,我总结了以下:

else if(input.at(i) == input.at(input.length())){ 
    string subString = input.substr(begin, (input.length() - begin)); 
    result.push_back(subString); 
} 

不过,我不断收到出界失误上述部分。它似乎有分裂的子字符串的边界问题,我不知道如何解决它。任何帮助?

+0

我建议存储最后一次拆分出现的索引,并在循环结束时,如果该值不是字符串的结尾,则将最后一次拆分后的所有内容你的结果。你现在拥有的东西有点令人怀疑,因为它会考虑与最后匹配的字符相同的字符(除了出界问题外)。 –

+1

你有没有试过增加一辆卡车?即为您的字符串附加一个分隔符。 –

+0

所以你想要使用两个分隔符'-'和'&'? – Raindrop7

回答

1

在您的代码中,您必须记住.size()将比您的最后一个索引多1个,因为它从0开始。因此,大小为1的数组索引为[0]。所以如果你做input.at(input.length())总是会溢出1个地方。 input.at(input.length() - 1)是最后一个元素。这里是一个为我工作的例子。你的循环刚刚抓住了最后一个字符串。

if(begin != input.length()){ 
    string subString = input.substr(begin,(input.length()-begin)); 
    result.push_back(subString); 
} 
+0

工程就像一个魅力!谢谢您的帮助。 –

0

从代码工作中的问题,我已经取代迭代器,以便我们可以检查输入的end()

int main() { 
    string input = "comma-delim-delim&delim-delim"; 
    vector<string> result; 
    vector<char> delims; 
    delims.push_back('-'); 
    delims.push_back('&'); 
    auto begin = input.begin(); // use iterator 

    for(auto ii = input.begin(); ii <= input.end(); ii++){ 
     for(auto j : delims) { 
      if(ii == input.end() || *ii == j){ 
       string subString(begin,ii); // can construct string from iterators, of if ii is at end 
       result.push_back(subString); 
       if(ii != input.end()) 
        begin = ii + 1; 
       else 
        goto done; 
      } 
     } 
    } 
done: 
    return 0; 
} 
+1

为什么你决定使用[goto](https://xkcd.com/292/)而不是简单的'break'? – scohe001

+0

@ scohe001'break'只会从内部for循环中退出,而外部循环会进入'end()'这意味着'ii ++'不会被允许。 – wally

+0

啊,我的坏,我看到goto,并得到了隧道视野。虽然标志不会[更好的C++实践](https://stackoverflow.com/questions/46586/goto-still-considered-harmful)? – scohe001

0

此程序使用std::find_first_of解析多个分隔符:

int main() { 
    string input = "comma-delim-delim&delim-delim"; 
    vector<string> result; 
    vector<char> delims; 
    delims.push_back('-'); 
    delims.push_back('&'); 
    auto begin = input.begin(); // use iterator 

    for(;;) { 
     auto next = find_first_of(begin, input.end(), delims.begin(), delims.end()); 
     string subString(begin, next); // can construct string from iterators 
     result.push_back(subString); 
     if(next == input.end()) 
      break; 
     begin = next + 1; 
    } 
}