在哪里检查错误以及如何

时间:2012-02-15 16:09:17

标签: c++ error-handling

我有一个代码设计问题。 我的问题是我应该在哪里放置我的用户错误处理代码以及我应该使用哪种方法。

情况是这样,我的用户应该为函数提供文件名,然后该函数尝试打开文件并对其进行操作。如果文件不存在,我想通知用户,并使用新输入的文件名再次尝试。据我所知std异常处理不适合这种情况。 现在我相信我有几个选择;在调用函数之前检查文件是否存在, 检查它是否存在于函数内并返回true表示是否成功,或者如果不调用打印消息的函数则检查文件是否存在,并允许在返回原始函数之前更改名称。

首选哪种方法以及为什么我应该使用更好的替代/ lib功能。

如果问题无关紧要,请提前致谢并对不起,但我想尝试将这些事情做好。

3 个答案:

答案 0 :(得分:3)

通常,您应该在获得文件名后尝试打开文件,如果失败则循环。该函数应该采用std::istream&,而不是文件名。至少在你展示的小场景中。或者,该函数可以采用文件名,并返回一个错误代码,指示它是否无法打开文件。有些情况(不是非常频繁,但确实存在),使用异常的替代方案有更多的缺点,因此异常将是最合适的解决方案。

答案 1 :(得分:2)

我不会轻易忽视例外,并说它们不合适。它只取决于整体设计 - 例如您的客户端是否启用了异常处理。您可以构建您的异常类层次结构,并让我们说CFileException(继承自std::exception),然后CFileNotFoundExceptionCFileAccessDeniedException ...等....继承自它。如果您的客户很乐意处理此类异常 - 请使用它们!您可以在异常对象中传递有关错误的更多信息,而不是错误代码,您的客户端可以决定该异常的处理位置。

另一种解决方案是为不同的错误返回不同的错误代码。不要只返回true / false - 它不会向客户提供太多信息(为什么功能失败)。客户端需要测试错误代码并相应地向用户生成消息(错误描述,错误原因)。如果您使用异常,则可以在失败的函数中创建该消息 - 这是包含有关错误及其性质的更多信息的上下文,因此可以创建更具描述性的消息。

关于将你的功能分解为更小的功能:你说“功能然后尝试打开文件并操纵它”所以值得拥有两个独立的功能 - 一个打开文件,另一个打开文件处理它。异常/错误的相同规则适用 - 如果打开文件失败,将抛出异常而不会输入第二个异常。

答案 2 :(得分:1)

如果需要函数的特定输入,除了尝试构建高性能应用程序之外,如果意外的参数会导致意外行为,则应始终检查函数内部的参数。这就是std::invalid_argument<stdexcept>的用途。

当然,您应该始终尝试确保您提供给您的过程的参数是正确的。但是如果你的功能可以告诉你某些东西当前出错了,它不会对你造成伤害。由于您的程序无法读取std::cout,因此您必须坚持异常或返回错误代码。

#include <iostream>
#include <fstream>
#include <stdexcept>
#include <string>

void myFunction(const std::string& inputFileName){
    std::ifstream myFile(inputFileName.c_str());
    if(!myFile.good())
        throw std::invalid_argument("The file does not exist!\n");
    /* other operations */
}

int main(){
    std::string userInput;

    std::cin >> userInput;
    while(userInput != "quit"){
        try{
            myFunction(userInput);
        }catch(const std::invalid_argument& e){
            std::cout << e.what();
        }
        std::cin >> userInput;
    }
    return 0;    
}
/* this code is just a small example and could be improved */