C 遍历文本文件时的分段错误

C 遍历文本文件时的分段错误,c,gcc,segmentation-fault,C,Gcc,Segmentation Fault,我有这段代码,它应该一个字符一个字符地读取一个文本文件,然后用它做一些事情,但是代码在第6行继续分段 #include <stdio.h> int main(void) { printf("a\n"); FILE* fp = fopen("~/pset5/dictionaries/small", "r"); for (int a = fgetc(fp); a != EOF; a = fgetc(fp)) { printf("b\n"

我有这段代码,它应该一个字符一个字符地读取一个文本文件,然后用它做一些事情,但是代码在第6行继续分段

#include <stdio.h>

int main(void) 
{
    printf("a\n");
    FILE* fp = fopen("~/pset5/dictionaries/small", "r");
    for (int a = fgetc(fp); a != EOF; a = fgetc(fp))
    {
        printf("b\n");        
    }
    return 0;
}
我还使用valgrind运行了它,如
valgrind--leak check=full./test
,test是可执行文件的名称,下面是相关的错误消息:

==7568== Invalid read of size 4
==7568==    at 0x4EA8A21: getc (getc.c:38)
==7568==    by 0x4005ED: main (test.c:6)
==7568==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==7568== 
==7568== 
==7568== Process terminating with default action of signal 11 (SIGSEGV)
==7568==  Access not within mapped region at address 0x0

我在这里真是不知所措,有人能解释一下这个分段错误是怎么回事吗?为什么第一次调用
printf
不打印任何东西?

您忘了检查
fopen()
的返回值是否为NULL,这表明在尝试打开文件时出错

您的
for
循环繁忙地使用空指针,因此您会得到segfault

检查全局变量
errno
,以了解更多关于您的案例中到底出了什么问题。

正如调试器所说(
fp=0x0
),您正在使用空指针调用
fgetc
。这就是导致坠机的原因

fp
为空,因为
fopen
调用失败。您需要检查错误


打开文件失败,因为您很可能没有名为
~
的目录。回想一下,在键入命令时,将
~
扩展到主目录是由shell完成的
fopen
只接受真实的文件名。

是否检查了
fopen()
的返回值?如果完全删除for循环并从命令行提示符执行(以使输出在程序结束后保持可见),会发生什么?那么第一个printf是否可见?然后返回for循环并以相同的方式重试。@Yunnosch现在将尝试该操作。@Yunnosch现在可以工作了,谢谢!我注释掉for循环,重新编译,然后取消注释掉for循环并重新编译,现在它在分段错误之前打印。不知道为什么它现在可以使用printf语句,但它确实可以。自1839年以来,通过魔术远程解决软件错误。事实上,melmomene的评论也针对类似的问题。不是最新的,执行方式等等。@chilliefiber你如何运行这个程序?@chilliefiber什么让你认为你的失败是在printf而不是在循环中?@Yunnosch
“a\n”
没有打印。啊,第一个printf,好的。这部分是我的误解。但您(OP)可能希望以更简单的方式引用该printf@辣椒纤维我无法解释。默认情况下,终端的输出应为行缓冲。您确定
test
是最新的吗?如果删除
/test
,重新编译代码并再次运行,会发生什么情况?
==7568== Invalid read of size 4
==7568==    at 0x4EA8A21: getc (getc.c:38)
==7568==    by 0x4005ED: main (test.c:6)
==7568==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==7568== 
==7568== 
==7568== Process terminating with default action of signal 11 (SIGSEGV)
==7568==  Access not within mapped region at address 0x0