我在以下程序中遇到了分段错误 为什么会发生这种情况?我该如何解决?
#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;
}
答案 0 :(得分:2)
我不知道原因
您的代码存在多个问题。一个明显的问题是您未能在v
函数中返回向量split_words
。不从返回值的函数返回值未定义的行为。
第二个问题是,j
在最后一个单词的末尾不合适,因为您的循环仅在s[j]
为空时停止。字符串不会以空白字符结尾,因此您的循环会超出字符串的长度。
话虽如此,如果您的目标是在空格字符上拆分字符串,则无需编写此类代码来完成工作。相反,只需使用std::istringstream
和operator >>
:
#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;
}
循环只是在流上调用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;
}