使用fgets()进行分段错误

时间:2015-09-02 15:12:11

标签: c arrays fgets

我正在制作一个基本程序,并决定使用函数和指针,在第一个输入中我可以选择键入," kitchen"或"楼上",然而,当我使用fgets()时,我遇到了分段错误,并且不知道为什么。我试图打印出字符串,看看我是否得到了正确的输出,当然由于分段错误,它没有发生。

以下是代码:

#include <stdio.h>
#include <string.h>
char one(char *oOne[]);
void two();
void three();

int main() {
    char *oOne[10], oTwo[10], oThree[10]; // Options one, two, and three.
    puts("WELCOME TO ASAD'S ADVENTURE");
    puts("");
    one(oOne);
    return 0;
}

char one(char *oOne[]) {
    puts("You are in a creepy house! Would you like to go \"upstairs\", or into the \"kitchen\"?");

    printf("\n> ");

    if (fgets(*oOne, sizeof *oOne, stdin) == NULL) { // Receiving the input from the user, and removing the \n caused by fgets().
        puts("EOF Occurred");
        return 1;
    }

    *oOne[strcspn(*oOne, "\n")] = 0;
    printf("%s\n", *oOne);
    // puts(*oOne);
}

以下是我收到的输出:

WELCOME TO ASAD'S ADVENTURE

You are in a creepy house! Would you like to go "upstairs", or into the "kitchen"?

> kitchen
Segmentation fault

如何修复分段错误?

2 个答案:

答案 0 :(得分:6)

C中的字符串是指向字符的类型,例如:

char *oOne;

或者是一个字符数组,如果你想静态分配你的记忆:

char oOne[10];

不是指向字符数组的指针,这就是你所拥有的:

char *oOne[10];

你需要:

char oOne[10];

然后:

one(oOne);

然后使用正确的类型修改one函数:

char one(char *oOne)
{
    if (fgets(oOne, sizeof oOne, stdin) == NULL)
    {
            puts("EOF Occurred");
            return 1;
    }

    *(oOne + strcspn(oOne, "\n")) = 0;

    printf("%s\n", oOne);


}

虽然我会传递明确的长度,而不是使用 sizeof,因为这不能使用动态分配的字符串:

car one(char *oOne, int len)
{
    if (fgets(oOne, len, stdin) == NULL)
    {
            puts("EOF Occurred");
            return 1;
    }

    // etc...
}

答案 1 :(得分:2)

我认为你得到了段错误,因为你在if (fgets(*oOne, sizeof *oOne, stdin) == NULL)中取消引用oOne。使用char *oOne[]上的左右规则,你得到的oOne是一个指向字符的指针数组,所以你拥有的是一个字符串数组而不是字符串。因此,要使用fgets,您希望在您的情况下使用单个String而不是字符串数组。因此,将oOne定义为char oOne[BUFSIZ]。这为您提供了一个字符串,在最大值时,您可以接收bufsiz字符,这是缓冲区的大小,您无法重复此操作。

因此,为了修复您的代码,它看起来像这样:

char *oOne[10], oTwo[10], oThree[10]更改为char oOne[10], oTwo[10], oThree[10]

char one(char *oOne[])更改为char one(char * oOne)

fgets(*oOne, sizeof *oOne, stdin)更改为fgets(oOne, sizeof oOne, stdin)

*oOne[strcspn(*oOne, "\n")]更改为oOne[strcspn(oOne, "\n")]

这样您就可以将oOne作为字符串(字符数组)而不是字符指针数组进行交互。有关如何在工作中定义变量的更多信息,请查看此处的左右规则http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html