gpt4 book ai didi

c - (C 编程)制作一个像 argv 一样的 char ** 数组

转载 作者:太空宇宙 更新时间:2023-11-04 07:07:45 25 4
gpt4 key购买 nike

在我正在编写的程序中,我创建了一个 Tokenize 结构,它说:

TokenizerT *Tokenize(TokenizerT *str) {

TokenizerT *tok;
*tok->array = malloc(sizeof(TokenizerT));
char * arr = malloc(sizeof(50));
const char *s = str->input_strng;
int i = 0;

char *ds = malloc(strlen(s) + 1);
strcpy(ds, s);

*tok->array[i] = strtok(ds, " ");

while(*tok->array[i]) {
*tok->array[++i] = strtok(NULL, " ");
}
free(ds);
return tok;
}

其中 TokenizeT 定义为:

struct TokenizerT_ {
char * input_strng;
int count;
char **array[];
};

所以我想做的是从我已经创建的大 token 中创建更小的 token 。我在返回数组时遇到问题,所以我将数组作为 TokenizerT 结构的一部分,这样我就可以通过执行 tok->array 来访问它。我在构建程序时没有收到任何错误,但是当我尝试打印 token 时出现问题。

TokenizerT *ans;
TokenizerT *a = Tokenize(tkstr);
char ** ab = a->array;
ans = TKCreate(ab[0]);
printf("%s", ans->input_strng);

TKCreate 可以工作,因为我用它来打印 argv,但是当我尝试打印 ab 时,它不起作用。我想它会像 argv 一样工作。如果有人可以帮助我,我将不胜感激。谢谢。

最佳答案

创建分词器

我要冒着风险出去,并猜测其意图:

TokenizerT *tok;
*tok->array = malloc(sizeof(TokenizerT));
char * arr = malloc(sizeof(50));

是动态分配单个 TokenizerT,其容量包含 49 个字符串和一个 NULL 结束标记。 arr 没有在代码中的任何地方使用,tok 也从未被赋值;如果每个值都向上移动一个语句并进行更正,这似乎更有意义:

// Note: I use 'sizeof *tok' instead of naming the type because that's
// my style; it allows me to easily change the type of the variable
// being assigned to. I leave out the parentheses because
// that makes sure that I don't provide a type.
// Not everyone likes this convention, but it has worked pretty
// well for me over the years. If you prefer, you could just as
// well use sizeof(TokenizerT).
TokenizerT *tok = malloc(sizeof *tok);
// (See the third section of the answer for why this is not *tok->array)
tok->array = malloc(50 * sizeof *tok->array);

(tok->array 不是一个好名字。我会使用 tok->argv 因为你显然是想产生一个 argument vector,这是一个的常规名称。在这种情况下,tok->count 可能是 tok->argc ,但我不知道您对该成员的意图是什么,因为您从未使用过它。)

填充参数 vector

strtok 将覆盖给定字符串中的(一些)字节,因此创建副本(此处为 ds)是完全正确的,并且您的代码这样做是正确的。但请注意,strtok 返回的所有指针都是指向副本中字符 的指针。因此,当您调用 free(ds) 时,您释放了所有这些 token 占用的存储空间,这意味着您刚刚创建的新 TokenizerT返回一个毫无戒心的调用者,充满了悬空指针。所以那永远不会做;在不再需要参数 vector 之前,您需要避免释放这些字符串。

但这会导致另一个问题:字符串将如何被释放?你没有保存ds的值,有可能strtok返回的第一个token不是从ds开始的. (如果字符串中的第一个字符是空格字符,就会发生这种情况。)如果您没有指向已分配存储空间的最开始的指针,则无法释放存储空间。 p>

TokenizerT 结构

char 是一个字符(通常是一个字节)。 char* 是指向字符的指针,通常(但不一定)是指向以 NUL 结尾的字符串开头的指针。 char** 是指向字符指针 的指针,通常(但不一定)是字符指针数组中的第一个字符指针。

那么什么是char** array[]? (注意尾随 [])。 “很明显”,它是一个未指定长度的char**数组。因为没有指定数组的长度,所以是一个“不完整类型”。现代 C 允许使用不完整的数组类型作为 struct 中的最后一个元素,但这需要您知道自己在做什么。如果您使用 sizeof(TokenizerT),您将得到结构的大小,没有不完整的类型;也就是说,数组的大小就好像是 0(尽管这在技术上是非法的)。

无论如何,这不是您想要的。您想要的是一个简单的 char**,它是参数 vector 的类型。 (它char*[] 相同,但是这两个指针都可以由整数 i 索引以返回 i th 字符串,所以它可能已经足够好了。)


这不是此代码的所有错误,但这是修复它的良好开端。祝你好运。

关于c - (C 编程)制作一个像 argv 一样的 char ** 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31195258/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com