繁体   English   中英

带有一个输入的 strcmp 的分段错误

[英]Segmentation Fault With Strcmp With One Input

我遇到了以下代码的问题。

我有一个全局变量

char tokens[512][80];

连同代码:

int main(int argc, char** argv) {
    char *input = malloc(sizeof(char) * 80);

    while (1) {
        printf("mini-shell>");
        fgets(input, 80, stdin);
        parse(input);

        if (strcmp(tokens[0], "cd") == 0) {
            cd();
        }
        else if (strcmp(tokens[0], "exit") == 0) {
            exit(1);
        }
    }
}

void parse(char str[]) {
    int index = 0;
    char* str_ptr = strtok(str, " ");

    while (str_ptr != NULL) {
        strcpy(tokens[index], str_ptr);
        str_ptr = strtok(NULL, " \0\r\n");
        //printf("%d\n", index);
        index = index + 1;
    }
}

我发现如果我为 stdin 输入exit我会得到一个分段错误,但是如果我为 stdin 输入cd ..我不会。 为什么会这样?

我们不知道cd()函数的定义是什么,但是您可能希望在此程序中考虑许多事情。

首先,我认为为input缓冲区动态分配 80 字节内存没有任何好处,因为您可以使用char input[80];在堆栈上轻松地自动分配char input[80]; - 这是免费且简单的,完成后无需重新分配。

如果你这样做,你可以用fgets(input, sizeof input, stdin)导出大小,如果你将输入行的大小从 80 更改为其他数字,则只需更改一次:数组上的sizeof拉直接看尺寸。

您的parse()例程也需要一点帮助。 如图所示通过extern声明函数是一个非常好的主意,这样当编译器看到您在循环中调用函数时(就在fgets ),它就知道参数和返回类型。 否则它必须做出假设。

由于parse()将您从输入中读取的行分开,因此不需要将字符串复制到其他位置,因此您可以将tokens从多维数组转换为简单的指针数组。 当您通过该行运行strtok()以拆分参数时,您可以只存储指针,知道它们将指向稳定数据,直到下一个fgets()

另外:您的代码并不严格要求或使用它,但是在tokens列表的末尾添加一个NULL指针是一个非常好的主意:否则,调用者如何知道实际输入了多少参数? 此代码检查用户是否只输入了一个空行。

我们还稍微改变了循环,因此strtok()只调用一次而不是两次,包括注释中提到的\\n

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *tokens[512];

extern void parse(char *str);

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

    while (1) {
        printf("mini-shell> "); fflush(stdout); // make sure user sees prompt
        fgets(input, sizeof input, stdin);
        parse(input);

        if (tokens[0] == NULL) continue; // user entered blank line

        if (strcmp(tokens[0], "cd") == 0) {
            cd();
        }
        else if (strcmp(tokens[0], "exit") == 0) {
            exit(1);
        }
    }
}

void parse(char *str) {
    int index = 0;

    char* str_ptr;

    while ( (str_ptr = strtok(str, " \n")) != NULL)
    {
        tokens[index++] = str_ptr;
        str = NULL; // for next strtok() loop
    }
    tokens[index] = NULL;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM