使用fopen()检查文件存在时触发Read access violation错误的原因及解决
调用fopen()触发Read access violation的原因及修复方案
我来帮你拆解这个问题,你的代码里有两个关键错误直接导致了这个访问违规:
错误1:fopen的模式参数用了字符而非字符串
fopen函数的第二个参数要求是字符串常量(比如"r"),但你写的是'r'——这是单个字符。在C语言里,当你把一个字符传给需要指针的参数时,它会被转换成对应的ASCII码值('r'的ASCII是0x72),程序会尝试把这个数值当作内存地址去访问,这显然是不属于你的程序的非法内存,直接触发Read access violation。
错误2:未检查命令行参数数量就访问argv[2]
你直接用*(argv+2)(也就是argv[2])来获取文件名,但如果运行程序时没有传入足够的命令行参数(比如只输入了程序名,没传额外参数),argv数组的长度可能只有1或2,argv[2]会是NULL。对NULL指针进行访问(fopen内部会尝试读取这个指针指向的内容),同样会导致访问违规。
修复方案
针对这两个问题,我们可以这样修改:
- 把
'r'改成"r",传给fopen正确的模式字符串。 - 在访问
argv[2]之前,先检查命令行参数的数量是否足够(argc至少为3,因为argc包含程序名本身)。 - 建议把fopen的返回值存到指针变量里,方便后续操作和调试,同时记得打开成功后要关闭文件。
修正后的代码示例:
#include <stdio.h> #include <stdbool.h> int main(int argc, char** argv) { bool quit = false; FILE* fp = NULL; // 先检查参数数量是否达标 if (argc < 3) { printf("Invalid input! Not enough arguments.\n"); quit = true; } else { // 用正确的字符串模式调用fopen fp = fopen(argv[2], "r"); if (fp == NULL) { printf("Invalid input! File does not exist or cannot be opened.\n"); quit = true; } else { // 文件打开成功,后续操作后记得关闭 fclose(fp); } } return quit ? 1 : 0; }
额外提醒:用fopen检查文件存在的方式有局限性——比如文件存在但你没有读取权限时,fopen也会返回NULL。如果只是单纯检查文件是否存在,POSIX系统可以用access()函数,Windows下可以用_access(),不过你的场景如果是要打开文件操作,上面的代码已经能满足需求了。
内容的提问来源于stack exchange,提问作者Arik gorun
相关产品推荐
相关产品推荐

