如何在 C 中创建一个函数,允许我根据分隔符将字符串拆分为数组?
How do I create a function in C that allows me to split a string based on a delimiter into an array?
我想在 C 中创建一个函数,这样我就可以向该函数传递一个字符串和一个定界符,它会 return 给我一个数组,其中的字符串部分基于分隔符。常用于将句子分成单词。
例如:"hello world foo"
-> ["hello", "world", "foo"]
但是,我是 C 的新手,很多指针的东西让我感到困惑。我主要从 this question 得到了答案,但它是内联的,所以当我尝试将它分成一个函数时,指针的逻辑让我感到困惑:
这是我目前拥有的:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void split_string(char string[], char *delimiter, char ***result) {
char *p = strtok(string, delimiter);
int i, num_spaces = 0;
while (p != NULL) {
num_spaces++;
&result = realloc(&result, sizeof(char *) * num_spaces);
if (&result == NULL) {
printf("Memory reallocation failed.");
exit(-1);
}
&result[num_spaces - 1] = p;
p = strtok(NULL, " ");
}
// Add the null pointer to the end of our array
&result = realloc(split_array, sizeof(char *) * num_spaces + 1);
&result[num_spaces] = 0;
for (i = 0; i < num_spaces; i++) {
printf("%s\n", &result[i]);
}
free(&result);
}
int main(int argc, char *argv[]) {
char str[] = "hello world 1 foo";
char **split_array = NULL;
split_string(str, " ", &split_array);
return 0;
}
要点是我有一个接受字符串、定界符和指向保存结果位置的指针的函数。然后它构造结果。结果的变量开始时为 NULL 且没有内存,但我会根据需要逐渐为其重新分配内存。
但正如我所说,我对指针真的很困惑。我知道我的结果是 char **
类型的字符串,它是 char *
类型的字符串,并且有很多结果,所以你需要指向每个结果,但是我应该传递 那个char **
的location给新函数对吧,所以就变成了char ***
?当我尝试使用 &
访问它时,尽管它似乎不喜欢它。
我觉得我在这里遗漏了一些基本的东西,我真的很感激深入了解代码出了什么问题。
您将解除引用与 寻址 混淆了(这完全相反)。顺便说一句,我在函数的任何地方都找不到 split_array
,因为它在 main
中。即使您的解引用和寻址正确,这仍然会有其他问题。
我很确定你正在尝试这样做:
#include <stdio.h>
#include <stdlib.h>
void split_string(char string[], const char *delimiter, char ***result)
{
char *p = strtok(string, delimiter);
void *tmp = NULL;
int count=0;
*result = NULL;
while (p != NULL)
{
tmp = realloc(*result, (count+1)*sizeof **result);
if (tmp)
{
*result = tmp;
(*result)[count++] = p;
}
else
{ // failed to expand
perror("Failed to expand result array");
exit(EXIT_FAILURE);
}
p = strtok(NULL, delimiter);
}
// add null pointer
tmp = realloc(*result, (count+1)*sizeof(**result));
if (tmp)
{
*result = tmp;
(*result)[count] = NULL;
}
else
{
perror("Failed to expand result array");
exit(EXIT_FAILURE);
}
}
int main()
{
char str[] = "hello world 1 foo", **toks = NULL;
char **it;
split_string(str, " ", &toks);
for (it = toks; *it; ++it)
printf("%s\n", *it);
free(toks);
}
输出
hello
world
1
foo
老实说,如果使用函数结果而不是 in/out 参数,这会更清晰,但你选择了后者,所以你去吧。
祝你好运。
我想在 C 中创建一个函数,这样我就可以向该函数传递一个字符串和一个定界符,它会 return 给我一个数组,其中的字符串部分基于分隔符。常用于将句子分成单词。
例如:"hello world foo"
-> ["hello", "world", "foo"]
但是,我是 C 的新手,很多指针的东西让我感到困惑。我主要从 this question 得到了答案,但它是内联的,所以当我尝试将它分成一个函数时,指针的逻辑让我感到困惑:
这是我目前拥有的:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void split_string(char string[], char *delimiter, char ***result) {
char *p = strtok(string, delimiter);
int i, num_spaces = 0;
while (p != NULL) {
num_spaces++;
&result = realloc(&result, sizeof(char *) * num_spaces);
if (&result == NULL) {
printf("Memory reallocation failed.");
exit(-1);
}
&result[num_spaces - 1] = p;
p = strtok(NULL, " ");
}
// Add the null pointer to the end of our array
&result = realloc(split_array, sizeof(char *) * num_spaces + 1);
&result[num_spaces] = 0;
for (i = 0; i < num_spaces; i++) {
printf("%s\n", &result[i]);
}
free(&result);
}
int main(int argc, char *argv[]) {
char str[] = "hello world 1 foo";
char **split_array = NULL;
split_string(str, " ", &split_array);
return 0;
}
要点是我有一个接受字符串、定界符和指向保存结果位置的指针的函数。然后它构造结果。结果的变量开始时为 NULL 且没有内存,但我会根据需要逐渐为其重新分配内存。
但正如我所说,我对指针真的很困惑。我知道我的结果是 char **
类型的字符串,它是 char *
类型的字符串,并且有很多结果,所以你需要指向每个结果,但是我应该传递 那个char **
的location给新函数对吧,所以就变成了char ***
?当我尝试使用 &
访问它时,尽管它似乎不喜欢它。
我觉得我在这里遗漏了一些基本的东西,我真的很感激深入了解代码出了什么问题。
您将解除引用与 寻址 混淆了(这完全相反)。顺便说一句,我在函数的任何地方都找不到 split_array
,因为它在 main
中。即使您的解引用和寻址正确,这仍然会有其他问题。
我很确定你正在尝试这样做:
#include <stdio.h>
#include <stdlib.h>
void split_string(char string[], const char *delimiter, char ***result)
{
char *p = strtok(string, delimiter);
void *tmp = NULL;
int count=0;
*result = NULL;
while (p != NULL)
{
tmp = realloc(*result, (count+1)*sizeof **result);
if (tmp)
{
*result = tmp;
(*result)[count++] = p;
}
else
{ // failed to expand
perror("Failed to expand result array");
exit(EXIT_FAILURE);
}
p = strtok(NULL, delimiter);
}
// add null pointer
tmp = realloc(*result, (count+1)*sizeof(**result));
if (tmp)
{
*result = tmp;
(*result)[count] = NULL;
}
else
{
perror("Failed to expand result array");
exit(EXIT_FAILURE);
}
}
int main()
{
char str[] = "hello world 1 foo", **toks = NULL;
char **it;
split_string(str, " ", &toks);
for (it = toks; *it; ++it)
printf("%s\n", *it);
free(toks);
}
输出
hello
world
1
foo
老实说,如果使用函数结果而不是 in/out 参数,这会更清晰,但你选择了后者,所以你去吧。
祝你好运。