c - 在 C 中重新实现 split 函数
问题描述
我一直在尝试编写一个函数,它将字符串作为一行并返回一个指向单词数组的指针。下面写的函数做了类似的事情我如何重写下面的代码1,但它应该比代码2更好,因为它能够更改分隔符。但是,code1 可以工作,但在内存分配期间,为 words 数组复制了相同的内存。从而造成单词重复。
代码 1:
char *split(const char *string) {
char *words[MAX_LENGTH / 2];
char *word = (char *)calloc(MAX_WORD, sizeof(char));
memset(word, ' ', sizeof(char));
static int index = 0;
int line_index = 0;
int word_index = 0;
while (string[line_index] != '\n') {
const char c = string[line_index];
if (c == ' ') {
word[word_index+ 1] = '\0';
memcpy(words + index, &word, sizeof(word));
index += 1;
if (word != NULL) {
free(word);
char *word = (char *)calloc(MAX_WORD, sizeof(char));
memset(word, ' ', sizeof(char));
}
++line_index;
word_index = 0;
continue;
}
if (c == '\t')
continue;
if (c == '.')
continue;
if (c == ',')
continue;
word[word_index] = c;
++word_index;
++line_index;
}
index = 0;
if (word != NULL) {
free(word);
}
return *words;
}
代码 2:
char **split(char *string) {
static char *words[MAX_LENGTH / 2];
static int index = 0;
// resetting words
for (int i = 0; i < sizeof(words) / sizeof(words[0]); i++) {
words[i] = NULL;
}
const char *delimiter = " ";
char *ptr = strtok(string, delimiter);
while (ptr != NULL) {
words[index] = ptr;
ptr = strtok(NULL, delimiter);
++index;
}
index = 0;
return words;
}
但是我注意到内存word+index
被重新分配到相同的位置,从而导致单词重复。
解决方案
strtok()
总是返回一个指向初始字符串的不同指针。这不会产生重复,除非您使用相同的输入字符串(可能使用新内容)调用它两次。
但是,您的函数返回一个指向static
数组的指针,该指针在每次调用时都会被覆盖,从而split()
使所有先前调用的结果无效。为了防止这种情况,
在每次调用中分配新内存(必须由调用者释放):
char *words = calloc(MAX_LENGTH / 2, 1);
或返回 a
struct
(始终按值复制):struct wordlist { char *word[MAX_LENGTH / 2]; }; wordlist split(char *string) { wordlist list = {}; /* ... */ list.word[index] = /* ... */; /* ... */ return list; }
推荐阅读
- javascript - 如何在数组中搜索产品“项目类型”并以“项目类型”的名称发送到工作表?
- while-loop - 嵌套while循环的代码时间复杂度
- mpdf - Mpdf 库不会在浏览器中输出 PDF 而总是下载
- javascript - 如何在 Angular 组件之间传递布尔值以切换样式的显示
- java - 如何挂钩 Android 类加载器?
- angular - 衡量 Angular 应用程序性能的最佳实践是什么?
- python - FileField() 未显示在模板中
- python-3.x - 对没有方法和其他类型的字符串进行排序
- database - 在mongodb聚合中使用key的值作为key
- node.js - npm 启动后的生命周期