C++ 建议处理while循环错误

C++ 建议处理while循环错误,c++,memory,while-loop,C++,Memory,While Loop,在通过while循环逐行读取文本文件的情况下,建议使用什么方法来处理错误 注意:使用fggets from 我可以考虑以下几种选择: 利用休息;摆脱while循环:但我需要 增加自由缓冲区;这可能导致。 使用try-and-catch,但是这也会处理这些函数中的所有其他异常,建议使用assert作为 建议。然而,assert将假定代码错误和中断操作,而 对于这种情况,程序可以继续执行,函数只需返回false。 对于上面的循环有什么建议?首先,试着抓住并不是一个完全坏的主意。您可以测试特定的错误并

在通过while循环逐行读取文本文件的情况下,建议使用什么方法来处理错误

注意:使用fggets from

我可以考虑以下几种选择:

利用休息;摆脱while循环:但我需要 增加自由缓冲区;这可能导致。 使用try-and-catch,但是这也会处理这些函数中的所有其他异常,建议使用assert作为 建议。然而,assert将假定代码错误和中断操作,而 对于这种情况,程序可以继续执行,函数只需返回false。 对于上面的循环有什么建议?

首先,试着抓住并不是一个完全坏的主意。您可以测试特定的错误并重新显示其余的错误,或者在一个拖网中捕获所有可能的错误,打印错误消息,然后关闭。这完全取决于您正在读取的数据类型、您合理期望看到的错误以及您需要执行的优雅错误恢复级别

至于使用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事件处理程序。

第一步:尽早处理错误,因此,如果无法稍微打开文件,请移动

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来确定是否继续循环,或者您可以在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,并删除了freebuffer调用

您可以将try块仅用于一行,因此其他函数不会导致任何问题, 示例如下所示。 如果您不确定某个缓冲区是否已清除,请使用xxx==nullptr来检查它 不会被删除两次。 对于第1点,如果要在使用FGET时捕获异常,请执行以下操作:

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
}

您可能首先在C++中重写这个。另外,您的程序有未定义的行为检查您对Buffer的实际操作我知道我使用的是C函数。什么是未定义的行为?fggets自动分配缓冲区。我知道我没有提供所有的类变量,比如m_error,它实际上是一个std::string。或者,您可以在每次释放之后设置缓冲区=NulLPTR,然后在任何时候从错误的while循环中中断,如果缓冲区不是NulLPTR,则释放它。如果在C++中用STD::String和标准I/O函数首先进行清理,则不需要清理。另外,RAII将确保执行清理,不需要gotoWhy来释放缓冲区,将其设置为NULL,稍后再次释放。释放空指针不是一个问题。就像我说的,这可能不是一个流行的方法,我个人也不是一个粉丝;虽然速度很快,但实际上在生产软件中出现的数量比你想象的要多。@quantdev:我之所以使用这些C函数是因为速度。我需要进行大量的文件访问,而最好的速度是通过使用这些而不是例如流来获得的。不理解您指出的危险-您是说内存不足,还是其他危险?如果我理解正确,FGET永远不会为您创建新阵列。它只是将读取的内容转储到数组中。char*buffer和调用fgets可能会导致内容被写入其他已在使用的内存空间。无论如何,我认为线程启动程序不太了解FGET,这里有一个链接。当然,如果这段代码是在VS中运行的,他们会告诉您null pointerExcept的用法。OP使用的不是fgets,而是fggets,其操作方式不同。每次调用它都会分配一个新字符串,不管是什么,都要按照原始帖子中的链接到zip文件的链接来检查ggets.c中的源代码-我刚刚做了一些修改-如果在阅读这行代码后出现问题,您的代码也不会显示如何处理-事实上,您当前的代码不会在try块中引发任何异常。。。这正是OP想要的解决方案,而不是如何阅读一行。基于我的问题,这确实是一个很好的解决方案。不幸的是,在check函数之间还有其他代码,如果check函数失败,则不允许执行这些代码。然后,在您的解决方案中,创建if{},else{if!函数{}块。当然,它是有效的,但它不是“美丽的”…很难根据问题之外的任何东西来回答问题。。。但是,如果您首先执行所有检查,那么您可以执行if res{…};自由缓冲区;如果res中断;当然,我完全同意!我简化了我的代码 我的问题可能太多了,如果我发布实际的代码,它将跨越整个页面。。。
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
}