2016-11-29 42 views
0

我在下面的程序中出现了分段错误。
为什么会发生这种情况,我该如何解决?从程序中创建一个向量的程序中的分段错误

#include <string> 
#include <vector> 
#include <iostream> 
#include <algorithm> 

std::vector<std::string> split_words(std::string s) { 
    std::vector<std::string> v(1, ""); 
    int i=0; 
    int wortanzahl = 0; 
    while(i<s.size()) { 
     if (s[i]!=' ') { 
      v.resize(wortanzahl + 1, ""); 
      for (int j=i; s[j]!=' '; ++j) { 
       v[wortanzahl] += s[j]; 
       i=j; 
      } 
      ++wortanzahl; 
     } 
     ++i; 
    } 
} 

int main() { 
    std::string s = "Alpha beta! Gamma"; 
    split_words(s); 
    return 0; 
} 
+3

使用'std :: istringstream'拆分空间上的单词。你不需要编写这些类型的循环来完成这项工作。 – PaulMcKenzie

+1

确保你有一个调试版本,然后在你的调试器下运行该程序。发生分段错误时,它会向您显示它发生的位置和程序状态。或者,您可以检查现有的核心文件。 PS,没有什么能阻止'j'跑完了...... – Useless

回答

0

我认为,只要你使用C++ 11或更高,你应该去正规表达式,做这样的事情:

std::vector<std::string> split_words(std::string s) { 
    std::vector<std::string> v; 
    std::regex pattern("[!-~]+"); 
    std::cmatch result; 

    while(regex_search(s.c_str(), result, pattern)) { 
     for(auto it : result) 
      v.push_back(it); 
     s = result.suffix().str(); 
    } 

    return v; 
} 

让您的每一个搜索匹配单个(非扩展的)ASCII表格字符组合,但不可打印的字符组合(包括空格),并且达到您的目标。

2

我不知道原因

你必须与你的代码的几个问题。最明显的一点是你没有返回split_words函数中的矢量v。不返回来自定义为返回值的函数的值是未定义的行为

第二个问题是j在最后一个单词上落下了句号,因为您的循环仅在s[j]为空时停止。字符串不会以空白字符结尾,因此您的循环会超出字符串的长度。在说了这个之后,如果你的目标是在空格字符上分割一个字符串,就没有必要写这样的代码来完成这项工作。只需使用std::istringstreamoperator >>

#include <vector> 
#include <sstream> 
#include <string> 
#include <iostream> 

std::vector<std::string> split_words(std::string s) 
{ 
    std::vector<std::string> v; 
    std::istringstream iss(s); 
    std::string temp; 
    while (iss >> temp) 
     v.push_back(temp); 
    return v; 
} 

int main() 
{ 
    std::string s = "Alpha beta! Gamma"; 
    auto vect = split_words(s); 
    for (auto& word : vect) 
     std::cout << word << "\n"; 
    return 0; 
} 

Live Example

循环只是简单地在流上调用operator >>,并在每次迭代呼吁push_back对遇到的每个分析的字符串。

0

当你忘记检查\0或字符串的长度时,错误就在这里。

for (int j=i; s[j]!=' ' && j < s.size(); ++j) { 
    v[wortanzahl] += s[j]; 
    i=j; 
} 

啊忘了我曾见过Alexsandrescu谈哨兵,所以你实际上可以解决的问题,如果你已经输入后添加一个(空间)。 在split_words作为第一行添加

s += ' '; 
0

需要这些变化。在下面的代码中也提到了内联。

// 0.可以尝试using namespace std;来清理代码。

// 1.在下面的循环中检查字符串的结尾。

// 2.返回字符串的向量。 (这修复了崩溃)。

// 3.使用向量输出拆分字符串。

#include <string> 
#include <vector> 
#include <iostream> 
#include <algorithm> 

// 0. can try using std to clean up code. 
std::vector<std::string> split_words(std::string s) 
{ 
    std::vector<std::string> v(1, ""); 
    int i=0; 
    int wortanzahl = 0; 
    while(i<s.size()) 
    { 
     if (s[i]!=' ') 
     { 
      v.resize(wortanzahl+1, ""); 
      // 1. check for end of string in below loop 
      for (int j=i; s[j] && s[j]!=' '; ++j) 
      { 
       v[wortanzahl] += s[j]; 
       i=j; 
      } 
      ++wortanzahl; 
     } 
     ++i; 
    } 

    // 2. return the vector of strings 
    return v; 
} 

int main() 
{ 
    std::string s = "Alpha beta! Gamma"; 
    std::vector<std::string> v = split_words(s); 

    // 3. output the split strings using vector 
    for (int i = 0; i < v.size(); ++i) 
     std::cout << v[i] << std::endl; 
    return 0; 
}