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

C语言中errno的设置时机及代码内错误触发场景咨询

关于C语言中errno的设置时机及你的代码分析

你的代码如下:

int FS_copyFile(const char* PathFrom , const char* PathTo) {
    FILE* Source;
    FILE* Target;

    struct stat st;
    stat(PathFrom, &st);

    char SourceFileData[st.st_size];

    Source = fopen(PathFrom , "r");

    if(Source == NULL) {
        return errno;
    }

    Target = fopen(PathTo , "w");

    if(Target == NULL) {
        return errno;
    }

    fgets(SourceFileData, st.st_size + 1, Source); 

    fputs(SourceFileData , Target);

    fclose(Source);
    fclose(Target);
}

针对你问的errno设置时机问题,结合C标准和你的代码,逐个说明:

哪些操作会设置errno?

C标准规定:只有标准库函数执行失败,且函数文档明确说明会设置errno时,才会修改errno;成功执行的函数不会改动errno(除非有特殊说明)。你的代码里这些操作可能触发errno:

  • stat(PathFrom, &st):当获取源文件属性失败时(比如文件不存在、权限不足),会设置errno。但你没检查stat的返回值,如果它失败,st.st_size是未定义的,后续创建数组会出问题。
  • fopen(PathFrom, "r"):打开源文件失败(文件不存在、权限不够等)时,返回NULL并设置errno,你这里的检查逻辑是对的。
  • fopen(PathTo, "w"):打开目标文件失败(路径无效、权限不足、磁盘满等)时,返回NULL并设置errno。
  • fgets(...):读取文件时发生IO错误(比如设备断开)会设置errno;但正常读到文件尾时,只会返回NULL,不会改errno。另外你用fgets读整个文件有问题,它遇到换行就会停止,没法正确读取带换行的大文件。
  • fputs(...):写入失败(磁盘满、写入中设备故障等)时,返回EOF并设置errno。
  • fclose(Source/Target):关闭文件时如果刷新缓冲区失败(比如磁盘满导致数据写不进去),会设置errno。你没检查fclose的返回值,会漏掉这类错误。

关于写入失败的errno时机

你问的“foo.txt无法写入”分两种情况:

  • 如果是连文件都打不开(比如权限不够、路径不存在且无法创建),errno会在fopen调用时就被设置;
  • 如果是打开成功但写入时出错(比如磁盘满、写入过程中权限被修改),errno会在fputs或fclose(刷新缓冲区时)调用时被设置。

内容的提问来源于stack exchange,提问作者ThePenguin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 14:02:43