C语言中基于fgets的故障分割

C语言中基于fgets的故障分割,c,shell,fgets,C,Shell,Fgets,当我在commandSplit函数中调用fgets时,我的代码不起作用。我通过在多个地方打印“我在这里吗”来解决这个问题,并发现fgets中的错误似乎是错误的。我可能错了,但我很肯定。我有一个分割错误,我不知道为什么。下面是我的代码 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h>

当我在
commandSplit
函数中调用
fgets
时,我的代码不起作用。我通过在多个地方打印
“我在这里吗”
来解决这个问题,并发现
fgets
中的错误似乎是错误的。我可能错了,但我很肯定。我有一个分割错误,我不知道为什么。下面是我的代码

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

#define MAX_CHARACTERS 512

int Execute(char *a[], int t[], int num) {
    int exitShell = 0;
    int l = 0;
    for (int i = 0; i < num; i++) {
        int status;
        if (strcmp(a[0], "quit") == 0) {
            exitShell = 1;
        }

        if (t[i] && ((strcmp(a[l], "quit") == 0))) {
            exitShell = 1;
        }
        char *holder[t[i]+1];
        for (int j = 0; j < t[i]; j++) {
            holder[j] = a[l];
            l++;
        }
        holder[t[i]] = NULL;
        pid_t p = fork();
        pid_t waiting;
        if (p == 0) {
            execvp(holder[0], holder);

            fprintf(stderr, "Child process could not execvp!\n");
            exit(1);
        } else {
            if (p < 0) {
                fprintf(stderr, "Fork FAILED!\n");
            } else {
                waiting = wait(&status);
                printf("Child %d exit with status %d\n", waiting, status);
            }
        }
        for (int g = 0; g < t[i]; g++) {
            a[g] = NULL;
        }
    }
    for (int i = 0; i < num; i++) {
        t[i] = 0;
    }
    return exitShell;
}

int commandSplit(char *c, FILE *f, char *a[], int t[]) {

    int count = 0;
    int emptyfile = 1;
    int stat = 0;
    int total1 = 0;
    char *temp[MAX_CHARACTERS];
    if (c != NULL) {
        char *readCommands = strtok(c, ";");
        while (readCommands != NULL) {
            temp[count] = readCommands;
            count++;
            readCommands = strtok(NULL, ";");
        }
        for (int i = 0; i  < count; i++) {
            char *read = strtok(temp[i], " ");
            int track1 = 0;
            while (read != NULL) {
                a[total1] = read;
                track1++;
                total1++;
                read = strtok(NULL, " ");
            }
            t[i] = track1;
        }
        stat = Execute(a, t, count);
    } else {
        char *buildCommands = "";
        printf("Am I here???\n");
        while ((fgets(buildCommands, MAX_CHARACTERS, f) != NULL) && !stat) {
            printf("Am I here???\n");
            emptyfile = 0;
            commandSplit(buildCommands, NULL, a, t);
            stat = Execute(a, t, count);
        }
        if (emptyfile) {
            printf("File is empty!\n");
            stat = 1;
        }
    }
    printf("Am I here???\n");
    return stat;
}

int main(int argc, char *argv[]) {

    int exitProgram = 0;
    FILE *fileRead = NULL;

    if (argc == 2) {
        fileRead = fopen(argv[1], "r");
        if (fileRead == NULL) {
            printf("No such file exists\n");
            exitProgram = 1;
        }
    }
    if (argc > 2) {
        printf("Incorrect batch mode call\n");
        exitProgram = 1;
    }

    char *args[MAX_CHARACTERS];
    int tracker[MAX_CHARACTERS];

    while (!exitProgram) {
        if (argc == 1) {
            char *commands = (char *)(malloc(MAX_CHARACTERS * sizeof(char)));
            printf("tinyshell>");
            if (fgets(commands, MAX_CHARACTERS, stdin) == NULL) {
                exitProgram = 1;
                printf("\n");
            }
            int len;
            len = strlen(commands);
            if (len > 0 && commands[len-1] == '\n') {
                commands[len-1] = '\0';
            }
            if (len > MAX_CHARACTERS) {
                printf("TOO MANY CHARACTERS - MAX: 512\n");
                continue;
            }

            if (strlen(commands) == 0)
                continue;

            exitProgram = commandSplit(commands, NULL, args, tracker);
        } else {
            exitProgram = commandSplit(NULL, fileRead, args, tracker);
        }
    }   

    fclose(fileRead);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义最大字符数512
int执行(字符*a[],int t[],int num){
int exitShell=0;
int l=0;
for(int i=0;i2){
printf(“不正确的批处理模式调用\n”);
exitProgram=1;
}
字符*参数[最大字符数];
整数跟踪器[最大字符数];
而(!exitProgram){
如果(argc==1){
char*命令=(char*)(malloc(MAX_CHARACTERS*sizeof(char));
printf(“tinyshell>”);
if(fgets(命令、最大字符数、标准输入)=NULL){
exitProgram=1;
printf(“\n”);
}
内伦;
len=strlen(命令);
如果(len>0&&commands[len-1]='\n'){
命令[len-1]='\0';
}
如果(长度>最大字符数){
printf(“字符太多-最大值:512\n”);
继续;
}
if(strlen(命令)==0)
继续;
exitProgram=commandSplit(命令、NULL、args、跟踪器);
}否则{
exitProgram=commandSplit(NULL、fileRead、args、tracker);
}
}   
fclose(fileRead);
返回0;
}
如评论所述,
buildCommands
指出空间不足和潜在的
const
空间

    char *buildCommands = "";
    ...
    // bad code
    while ((fgets(buildCommands, MAX_CHARACTERS, f) != NULL) && !stat) {
使用数组或
malloc()分配空间


char*buildCommands=”“;printf(“我在这里吗?”\n);while((fgets(buildCommands,MAX_CHARACTERS,f)!=NULL)&&!stat){
:您将一个0字节的缓冲区传递给fgets:您希望得到什么。当我初始化为char*buildCommands时,我得到一个错误,buildCommands可能无法设置,因此我认为可以将其设置为空并传入。我该如何解决这个问题?有趣的是:您在代码的其他地方做了正确的事情:
char*commands=(char*)(malloc)(MAX_CHARACTERS*sizeof(char));printf(“tinyshell>”);if(fgets(commands,MAX_CHARACTERS,stdin)==NULL){
我是个白痴。我只需要为它分配空间。这是解决方案char*buildCommands=(char*)(malloc(MAX_CHARACTERS)),或者你也可以做
char buildCommands[MAX_CHARACTERS]
这样你就不必在不需要的时候释放它(但它是本地的)
    char buildCommands[MAX_CHARACTERS];
    ...
    while ((fgets(buildCommands, sizeof buildCommands, f) != NULL) && !stat) {
      ...
    }

    // or 

    char *buildCommands = malloc(MAX_CHARACTERS);
    assert(buildCommands);
    ...
    while ((fgets(buildCommands, MAX_CHARACTERS, f) != NULL) && !stat) {
      ...
    }
    ...
    free(buildCommands);