c - 在 C 中使用 fgets 的段错误

标签 c shell fgets

我的代码不工作,当我在 commandSplit 函数中调用 fgets 时。我通过在多个地方打印 "Am I here" 来解决这个问题,发现错误似乎在 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;
}

最佳答案

如评论 @Jean-François Fabre , buildCommands 指向空间不足和潜在的 const 空间;

    char *buildCommands = "";
    ...
    // bad code
    while ((fgets(buildCommands, MAX_CHARACTERS, f) != NULL) && !stat) {

用数组或malloc()分配空间

    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);

关于c - 在 C 中使用 fgets 的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39551474/

相关文章:

c - 使用 fget 时出现奇怪的情况

从文本文件中一个一个地计算字符

c - 在 C 中,是否对只有一个元素的数组初始化进行了特殊处理?

c++ - 为什么 LD_LIBRARY_PATH 无效?

c++ - 链接 g++ minGW

java - shell脚本: java program can't find property file when starting by sh

C程序,设计支票

c++ - 链接上 undefined symbol ___gxx_personality_v0

python - 从 linux 命令行一次启动 python 脚本的多个实例

c - strcmp 在使用 fgets 读取的行上