gpt4 book ai didi

c - strtok 和 fgets 的奇怪数组行为

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

我正在开发一个充当 shell 解释器的程序,该程序读取带参数的命令并创建一个使用 execvp() 执行命令的子程序。我坚持执行一些字符串操作来收集字符数组 *args[],尤其是使用 fgetsstrtok 时。

这是我的代码的 MCVE。

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#define MAX_LINE 80

int main(void){
//initialize variables
char *args[MAX_LINE/2 + 1];
char input[MAX_LINE];
//char input[MAX_LINE] = "some sentence unknown"; // <-- this line works fine..

int counter = 0;
printf("COMMANDER>");
fflush(stdout);

//receive input
fgets(input,MAX_LINE,stdin);

//parse input
char *parser;
parser = strtok(input," \r\t");

//parse line
while(parser != NULL){
args[counter] = parser;
counter++;
parser = strtok(NULL," ");
}

//print results
int i = 0;
for(i = 0; i < counter + 1;i++){
printf("1");
printf(" - %d: %s\n",i,args[i]);
}

return 0;
}

这里的问题是输出。当我尝试运行它时,我得到以下输出:

COMMANDER>some sentence unknown
1 - 0: some
1 - 1: sentence
1 - 2: unknown

1 - 3: (null)

我的问题是空白。我不知道它从哪里来,无论我做什么它都会出现。

据我所知,它可能是字符串末尾的\n 字符或其他字符,但将其传递给 execvp 作为 execvp(args[0],args ) 会产生一个错误,因为它将此空行解释为“”的参数。

有一行我已经注释掉了,它只是 main 开头的一个字符串赋值。如果使用此赋值而不是 fgets,程序将运行并且我得到所需的输入:

COMMANDER>some sentence unknown
1 - 0: some
1 - 1: sentence
1 - 2: unknown
1 - 3: (null)

感谢阅读。我对我的 C 有点生疏,所以我自己坚持了几个小时,但仍然找不到解决方案。

最佳答案

如果您阅读例如this fgets reference你会看到它说

Parsing stops if end-of-file occurs or a newline character is found, in which case str will contain that newline character.

[强调我的]

您看到的“那个空白区域”是 fgets 在字符串末尾添加的换行符。


然而,您的代码中存在一个更糟的问题。

char *args[MAX_LINE/2 + 1];

您定义了一个指针数组,但是您让这个数组未初始化。在 C 中,未初始化的局部(和非静态)变量实际上 未初始化。它们的内容将不确定并且看起来几乎是随机的。

更具体地说,您碰巧在 args[counter] 处得到一个空指针纯属运气。

在未初始化的情况下尝试以任何方式使用此指针将导致 undefined behavior .

简单的解决方案是将数组显式初始化为充满空指针:

char *args[MAX_LINE/2 + 1] = { NULL };

以上将“零初始化”所有元素,对于指针来说这意味着它们将是 NULL

关于c - strtok 和 fgets 的奇怪数组行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52579474/

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