程序中的分段错误,它从字符串创建向量

时间:2016-11-29 17:42:39

标签: c++ arrays fault

我在以下程序中遇到了分段错误 为什么会发生这种情况?我该如何解决?

#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;
}

4 个答案:

答案 0 :(得分:2)

  

我不知道原因

您的代码存在多个问题。一个明显的问题是您未能在v函数中返回向量split_words。不从返回值的函数返回值未定义的行为

第二个问题是,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

答案 1 :(得分: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 :(得分:0)

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

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

忘了我曾经见过Alexsandrescu谈论过哨兵,所以如果你在输入后添加(空格),你实际上可以解决问题。 作为split_words添加

的第一行
s += ' ';

答案 3 :(得分:0)

这些更改是必需的。在下面的代码中也提到内联。

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

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

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

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

#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;
}