C++中的分割函数
Posted
技术标签:
【中文标题】C++中的分割函数【英文标题】:Splitting function in C++ 【发布时间】:2017-07-26 04:27:28 【问题描述】:我正在尝试编写一个函数,它将一个字符串和一个分隔符作为输入并返回一个字符串数组。由于某种原因,以下代码遇到分段错误。我想知道可能是什么问题?
char** split(string thing, char delimiter)
thing+='\0';//add null to signal end of string
char**split_string = new char*[100];
int i=0,j=0,l=0; //indexes- i is the ith letter in the string
// j is the jth letter in the lth string of the new array
int length = thing.length();
while (i < length)
if ((thing[i]!=delimiter && thing[i]!='\0'))
split_string[l][j]=thing[i];
j++;
else
j=0; //reset j-value
l++;
i++;
return split_string;
【问题讨论】:
为什么不将源字符串“拆分”成字符串向量?为什么要为指针和动态分配而烦恼(特别是如果源字符串中没有 100 个“令牌”)?split_string[l]
是一个未初始化的指针,其中包含一些随机垃圾,指向内存中的某个随机位置。 split_string[l][j]=thing[i]
然后尝试写入该随机内存位置。
你试过用谷歌搜索错误信息吗?了解它的确切含义?然后很容易找到你哪里出错了。
至于“拆分”字符串的一种可能(和 IMO 更简单)方式,请记住 std::getline
可以与任意 分隔符 字符一起使用。
最后,关于您的问题,您分配了一个包含 100 个 指针 的数组,但是您如何让所有这些指针实际指向?
【参考方案1】:
做完之后
char**split_string = new char*[100];
您仍然需要初始化您创建的 100 个 char * 指针中的每一个。
static const size_t str_len = 50; //assuming length will not exceed
for( size_t ix = 0 ; ix < 100 ; ++ix)
split_string[ix] = new char[str_len];
您还需要确保在写入 split_string 时不会超过分配的内存,在这种情况下它是 50 并且您没有超过 100 的拆分字符串。
【讨论】:
【参考方案2】:最好将std::string
拆分为std::vector<std::string>
。使用下面的函数
#include <sstream>
#include <string>
#include <vector>
std::vector<std::string> split(std::string str, char delim)
std::vector<std::string> result;
std::stringstream ss(str);
std::string token;
while (getline(ss, token, delim))
result.push_back(token);
return result;
【讨论】:
我猜 OP 正在为 split 函数编写一个实现,而getline
在内部进行所有检查。【参考方案3】:
1) 当您找到新的子字符串时,请为每个子字符串分配内存(类似于 char[l] = new char[100])。
由于您不知道开头本身的子串数量,请考虑使用向量。考虑使用向量 split_string。在循环中,当您找到一个新的子字符串时,您只需将该字符串推入向量中。最后,您将拥有向量中的所有拆分字符串。
【讨论】:
【参考方案4】:每个char *
都必须像这样单独初始化。
int len = 100;
char**split_string = new char*[len]; // len holds the number of pointers
for(int k = 0; k < len; k++)
split_string[k] = new char[500]; // holds len of string (here Max word size is considered 500)
在 C++ 中,更建议坚持使用 std::string 以降低复杂性并提高可读性。
在找到\0
之前,当您跳出while-loop 时,您的代码将无法 抓住最后一个子字符串。要解决此问题,您需要将 while (i < length)
更改为 while (i <= length)
。
使用向量:
vector<string> split(string thing, char delimiter)
int len = 100;
vector<string> v;
char c[500];
int i=0,j=0;
int length = thing.length();
while (i <= length)
if ( thing[i] != delimiter && thing[i] != '\0')
c[j]=thing[i];
j++;
else
c[j] = '\0';
v.push_back(c);
memset(c, 0, sizeof c);
j = 0;
i++;
return v;
Demo.
【讨论】:
以上是关于C++中的分割函数的主要内容,如果未能解决你的问题,请参考以下文章