在 C 中使用 fgets 时出现“分段错误:11”
Posted
技术标签:
【中文标题】在 C 中使用 fgets 时出现“分段错误:11”【英文标题】:"Segmentation fault: 11" when using fgets in C 【发布时间】:2022-01-14 21:16:50 【问题描述】:我正在用 C 语言编写一个命令行工具来控制 UNDERTALE 保存文件(因为为什么不这样做),每当我从用户那里获取输入时,我都会遇到分段错误。
这是我所有的代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#define KILOBYTE 1024
/* The 'm()' is so i know what line the fault happens on */
void m(void)
printf("X");
int main(int argc, char**argv)
FILE *file;
if (file = fopen("~/.undersave", "r"))
// Do some code that I haven't written yet
else
char path[KILOBYTE] = "";
printf("It seems that this is your fist time using UNDERSAVE.\nWe just need to go through some quick installation steps.\nWhere do you want your UNDERTALE save folder to be located? >>> ");
m();
fgets(path, KILOBYTE, stdin);
/*
The fault happens here, when it asks me,
i put in the input like normal, but
when I press enter, I get a fault before
it prints 'X'
*/
m();
mkdir(path, 0777);
m();
file = fopen("~/.undersave", "w");
m();
fprintf(file, "%s", path);
m();
fclose(file);
return 0;
【问题讨论】:
Re "'m()' 让我知道故障发生在哪条线路上",oof。学习使用调试器。gdb
可以很容易地给你一个堆栈跟踪(命令是bt
IIRC)。而且,如果您使用gcc
或clang
,您应该会发现-fsanitize=address
非常有用。
printf
使用缓冲输出,因此除非刷新输出缓冲区,否则您将看不到任何内容。通常,您只需在 printf 末尾使用换行符 ('\n'
) 即可。我推荐void m(int location) printf("X%d\n", location);
,然后将调用更改为m(1)
、m(2)
等。
另见how to remove the newline that fgets puts in the buffer。
【参考方案1】:
很可能两个对fopen
的调用都失败了,因为在类Unix 系统上~
-expansion 是shell 的一个特性,不适用于直接使用fopen
或@987654325 打开文件的程序@。如果要打开相对于主目录的文件,请包含完整路径,或使用getenv
读取HOME
环境变量并在程序中构造路径。或者,更好的是,使文件名成为命令行参数;这些参数在您的程序看到它们之前由 shell 扩展,因此 ~
扩展将起作用。
因此,fopen
用于写入返回 NULL,您无需对其进行测试(一个更严重的错误)。然后你尝试将fprintf
指向一个空文件指针,这自然会崩溃。
此外,您的 printf("X")
也不是一个好的诊断工具,因为到终端的输出通常是缓冲的。在打印新行或尝试从标准输入读取或发生其他一些特殊情况之前,X 实际上不会被写入屏幕。所以我怀疑程序实际上崩溃的时间比你想象的要晚,在fprintf
而不是fgets
上。查看Why does printf not flush after the call unless a newline is in the format string?,然后将fflush(stdout)
放在printf
之后的m()
函数中。
【讨论】:
如果有的话,做一些我还没写的代码,最好加进去。 哦等等,我现在明白了。这不是 fgets,因为 'm();'没有被冲走。真正的问题在于'fprintf(file,"%s",path);',未创建文件夹的原因是路径不存在。 (〜不存在)所以我只是假设它正在停止它。以上是关于在 C 中使用 fgets 时出现“分段错误:11”的主要内容,如果未能解决你的问题,请参考以下文章