gpt4 book ai didi

c - 无法在 C 中创建 shell(Seg-Fault 和 ferror)

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

我一直在学习如何制作我自己的 shell 的教程,但我已经被困了几天了。

两件事:

  1. 这段代码编译运行时,会随机出现段错误,我也想不通原因。
  2. if 语句 `if (ferror != 0)` 似乎总是正确的。这很奇怪,因为我不明白为什么 fgets()ma​​in() 函数中失败。

如能提供有关这些主题(或有关创建此 shell 的其他主题)的任何信息,我们将不胜感激。

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

#define MAXSIZE 512

int parseCmd(char *cmd, char *args[])
{
printf("LOGGER: parseCmd(cmd=%s, args=%p)\n", cmd, args);

char cmdDelims[] = {' ','>'};

char *cmdReader;
cmdReader = strtok(cmd, cmdDelims);

int i = 0;
while (cmdReader != NULL)
{
args[i] = strdup(cmdReader);

printf("LOGGER: args[%d]=%s\n", i, args[i]);

cmdReader = strtok(NULL, cmdDelims);
i++;
}
return 0;
}

void printToLine(char *args[])
{
int length;
length = sizeof(args) / sizeof(char);

int i = 0;
while (i < length)
{
printf("%s\n", args[i]);
i++;
}
}

int main(int argc, char *argv[])
{
char *in;
in = malloc(MAXSIZE);

char *args[15];
char *cmd = NULL;

int errorBit = 0;
int terminationBit = 1;
char error_message[30] = "An error has occurred\n";

char inDelims[] = "\n";

while (terminationBit)
{
printf("mysh>");

// get input from command line
fgets(in, MAXSIZE, stdin);
if (ferror != 0)
{
perror(error_message);
}

// get pointer to command line input w/o the newline
cmd = strtok(in, inDelims);

// parse the command into separate arguments
errorBit = parseCmd(cmd, args);
if (errorBit)
{
perror(error_message);
exit(1);
}

printToLine(args);

// check if the user wants to exit the shell
if (strcmp(*args, "exit") == 0)
{
terminationBit = 0;
}
}
return 0;
}

以下是一些输出:

**[ray@12] (6)$ mysh**
mysh>1 2 3
An error has occurred
: Success
LOGGER: parseCmd(cmd=1 2 3, args=0x7fff4a50b080)
LOGGER: args[0]=1
LOGGER: args[1]=2
LOGGER: args[2]=3
1
2
3
Segmentation fault (core dumped)
**[ray@12] (7)$ mysh**
mysh>1 2 3 4 5 6 7 8 9 10
An error has occurred
: Success
LOGGER: parseCmd(cmd=1 2 3 4 5 6 7 8 9 10, args=0x7fffba053d70)
LOGGER: args[0]=1
LOGGER: args[1]=2
LOGGER: args[2]=3
LOGGER: args[3]=4
LOGGER: args[4]=5
LOGGER: args[5]=6
LOGGER: args[6]=7
LOGGER: args[7]=8
LOGGER: args[8]=9
LOGGER: args[9]=10
1
2
3
4
5
6
7
8
mysh>1 2 3
An error has occurred
: Success
LOGGER: parseCmd(cmd=1 2 3, args=0x7fffba053d70)
LOGGER: args[0]=1
LOGGER: args[1]=2
LOGGER: args[2]=3
1
2
3
4
5
6
7
8

最佳答案

对于ferror错误,需要测试ferror(stdin),而不是ferror。后者是函数地址,永远不会为零:

if (ferror(stdin) != 0)
{
perror(error_message);
}

至少对于某些段错误,这不会按照您的想法进行:

length = sizeof(args) / sizeof(char);

这将告诉您有多少字节用于存储指针,具体是 4 还是 8,不是参数的数量。

因此,如果您有四个(或八个)参数,它将似乎有效。如果你有更多,它似乎会忽略一些参数。如果你有更少的参数,它会从 Void 中获取丢失的参数,导致(几乎可以肯定的)段错误。

您需要独立计算 length 并将其传递,或者在 args 中存储一些终止符,例如在您找到的最后一个有效参数之后添加一个 NULL 参数:

        cmdReader = strtok(NULL, cmdDelims);
i++;
}
args[i] = NULL;
return 0;
}

void printToLine(char *args[])
{
int i = 0;
while (args[i])
{
printf("%s\n", args[i]);
i++;
}
}

关于c - 无法在 C 中创建 shell(Seg-Fault 和 ferror),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12716276/

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