下面的代码:
#include <stdio.h>
#include "config.h"
#include <errno.h>
char buffer[50];
long long bufSize = 50;
FILE* fptr;
char* readConfig(char* buffer, size_t bufSize) {
fptr = fopen("config.txt", "rt");
if (fptr == NULL) {
return "error opening config file: %s", strerror(errno);
} else {
if ((fgets(buffer, bufSize, fptr)) == NULL) {
fclose(fptr);
return "error reading config file: %s", strerror(errno);
}
else {
fclose(fptr);
return buffer;
}
}
}
出于测试的目的,我删除了config.txt文件,这样fopen()函数应该返回NULL。会失败,但在两柴程式码时,它会略过“if(fptr == NULL){...}”部分,直接跳出函式。
继续调试过程时,我在尝试使用readConfig()的返回值“0xC 0000005”时收到以下错误:阅读位置0xFFFFFFFFA 4 E0 EB 70时发生访问冲突”
1条答案
按热度按时间tvmytwxo1#
1.无法编译您的代码,因为您共享了一个代码段(没有
main()
)并且未包含config.h。1.将
#include <string.h>
转换为strerror()
。1.建议调用方传入局部变量而不是全局变量。
1.使用
sizeof
来确定数组的大小,而不是在buffer[50]
和bufSize = 50;
中硬编码大小。另一个好的替代方法是定义一个常量。fopen()
模式“t”不是标准的,所以要么把它去掉,要么用windows或其他东西标记你的程序。1.当您返回错误时,请删除不必要的
else
&缩排。1.表达式
return "error opening config file: %s", strerror(errno);
没有按照你期望的方式工作,它将在void上下文中计算第一部分,然后返回第二部分strerror(errno)
。否则我无法重现任何不良影响。fgets()
在出现eof或错误时返回NULL,但不显示为设置errno
。如果需要,可以使用feof()
和/或ferror()
来确定是哪一个。1.在调用
fgets()
之后,在检查errno
之前调用fclose()
,因此它具有fclose()
调用的状态。1.返回错误消息或从文件中读取的值是不好的设计,因为您无法区分它们。更改为成功时返回NULL。
考虑让调用者打开文件并传入
FILE *
。它为您提供了灵活性,例如,使用stdin
作为文件句柄。当需要清理资源时,我更喜欢使用
goto
,而不是多个返回。这里有点冗长,但每个错误情况的处理方式都是一样的。当你交换参数时,你可以记录它们与最新编译器的关系: