使用 fgets() 的分段错误
Segmentation fault using fgets()
我正在制作一个基本程序,并决定在第一个输入中使用函数和指针,我可以选择输入 "kitchen" 或 "upstairs",但是当我使用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
如何修复分段错误?
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...
}
我认为您遇到了段错误,因为您正在取消引用 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 作为字符串(字符数组)而不是字符指针数组进行交互。有关如何在 see 中定义变量的更多信息,请查看此处的左右规则 http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html。
我正在制作一个基本程序,并决定在第一个输入中使用函数和指针,我可以选择输入 "kitchen" 或 "upstairs",但是当我使用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
如何修复分段错误?
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...
}
我认为您遇到了段错误,因为您正在取消引用 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 作为字符串(字符数组)而不是字符指针数组进行交互。有关如何在 see 中定义变量的更多信息,请查看此处的左右规则 http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html。