You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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内部会尝试读取这个指针指向的内容),同样会导致访问违规。


修复方案

针对这两个问题,我们可以这样修改:

  1. 把'r'改成"r",传给fopen正确的模式字符串。
  2. 在访问argv[2]之前,先检查命令行参数的数量是否足够(argc至少为3,因为argc包含程序名本身)。
  3. 建议把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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:55:41