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
相关产品推荐
相关产品推荐

