在通过while
循环逐行读取文本文件的情况下,建议的处理错误的方法是什么?
(注意:here使用了fggets
)
bool SomeClass::ReadFile(int ignorelines) {
FILE *file = fopen(m_filepath.c_str(), "r");
if (file!=NULL) {
char *buffer; //line reading buffer
while (fggets(&buffer,file)==0) { //read line (fggets returns non-zero at provided terminator or \eof)
if (ignorelines>0) {
ignorelines--; //count the lines ignored
free(buffer);
continue;
}
line.assign(buffer);
if (!PerformLineCheck1(buffer)) {
m_error+="The line is not allowed.\n";
free(buffer);
fclose(file);
return false;
}
if (!PerformLineModification1(buffer)) {
m_error+="The line could not be modified properly.\n";
free(buffer);
fclose(file);
return false;
}
if (!PerformLineExtraction(buffer)) {
m_error+="The variables could not be extracted.\n";
free(buffer);
fclose(file);
return false;
}
//extracted all, now continue with next line
free(buffer); //clear up the line
}
fclose(file);
return true;
}
m_error+="There was an error opening the data file.\n";
return false;
}
我可以想到一些选择:
break;
退出while
循环:但是我需要
添加free(buffer);
,这可能会导致freeing memory twice。try
和catch
,但这也处理了这些函数中的所有其他异常,并建议使用assert(as
建议here)。但是,断言将承担代码错误并中断操作
对于这种情况,程序执行可以继续,函数只需要返回false。对于类似上面的循环的建议有什么建议?
答案 0 :(得分:0)
首先,try
和catch
不是一个完全糟糕的主意。您可以测试特定错误并重新抛出其余错误,或者在一个dragnet中捕获每个可能的错误,打印错误消息并关闭。这完全取决于您正在阅读的数据类型,您将合理期望看到的错误,以及您需要执行的优质错误恢复级别。
至于使用break
,有一种方法可以在不进行双重免费的情况下执行此操作,但是,某些人可能不受欢迎。
基本上,它看起来像这样:
while (someCondition) {
// Do things
error = 1; // Error encountered
if (error)
goto cleanUp;
// Do some more things
}
// Do some other things that you need to do outside the loop here
:cleanUp
free(buffer);
return error;
它的操作类似于在某些语言中使用自定义onError事件处理程序。
答案 1 :(得分:0)
第一步:尽早处理错误,移动"如果我们无法打开文件"一点点。
bool SomeClass::ReadFile(int ignorelines) {
FILE *file = fopen(m_filepath.c_str(), "r");
if (file==NULL) {
m_error+="There was an error opening the data file.\n";
return false;
}
然后其余的代码使用res
变量来跟踪整个操作是否成功,以及序列末尾的单个if
来确定我们是否继续循环(或者,如果您愿意,可以while (res && fggets( ... ))
)。
char *buffer; //line reading buffer
bool result = true;
while (fggets(&buffer,file)==0) { //read line (fggets returns non-zero at provided terminator or \eof)
if (ignorelines>0) {
ignorelines--; //count the lines ignored
}
else
{
line.assign(buffer);
if (!PerformLineCheck1(buffer)) {
m_error+="The line is not allowed.\n";
res = false;
}
else if (!PerformLineModification1(buffer)) {
m_error+="The line could not be modified properly.\n";
res = false;
}
else if (!PerformLineExtraction(buffer)) {
m_error+="The variables could not be extracted.\n";
res = false;
}
}
//extracted all, now continue with next line
free(buffer); //clear up the line
if (!res) break;
}
fclose(file);
return res;
}
这减少了代码中的重复以释放和关闭。
(编辑:不是continue
的粉丝,我在第一个if之后将其更改为else
,并删除了free(buffer)
来电
答案 2 :(得分:0)
对于点号。 1,如果要在使用fgets()时捕获异常,请执行以下操作:
int result = 0;
while (true) {
char* buffer = new char[100]; //YOU MUST allocate space for the buffer,
//cannot use it directly
try {
result = fggets(&buffer,file);
}
catch () {
//do whatever you need to catch, break if necessary
//handling of memory is shown below
}
if (0 == result) {
if (nullptr != buffer) { // make sure when you execute delete[] or free, the pointer is valid
delete[] buffer;//or free
}
break;
}
//do your other things here
}