C++ fstream:检查错误的最正确方法
我想围绕C++ fstream:检查错误的最正确方法,c++,exception,error-handling,io,fstream,C++,Exception,Error Handling,Io,Fstream,我想围绕fstream类编写一个包装器。正如我所看到的,检查流是否正常工作的最常用方法是查看good()函数的结果。然而,我听说这大部分是历史函数,使用它并不安全(更准确地说,在某些情况下,流可能无法正常工作,但函数返回true。因此我想分享经验,并从其他人那里了解检查fstream错误的最正确方法 如果有可能检查不同类型的错误,比如文件不存在、只能打开读取等,那就太好了。也有必要让这些程序跨平台运行(不过,主要目标是Linux) 提前感谢!如果文件操作失败,并且eof()返回false,那么您
fstream
类编写一个包装器。正如我所看到的,检查流是否正常工作的最常用方法是查看good()
函数的结果。然而,我听说这大部分是历史函数,使用它并不安全(更准确地说,在某些情况下,流可能无法正常工作,但函数返回true
。因此我想分享经验,并从其他人那里了解检查fstream
错误的最正确方法
如果有可能检查不同类型的错误,比如文件不存在、只能打开读取等,那就太好了。也有必要让这些程序跨平台运行(不过,主要目标是Linux)
提前感谢!如果文件操作失败,并且
eof()
返回false
,那么您可以检查或(取决于平台)以找出问题所在。我只有两个建议,它们都依赖于使用重载!
运算符的返回值检查打开的流。
使用仅输入模式,只需检查文件是否存在:
char name[] = "C:\\some_folder\\some file.txt";
std::ifstream f;
f.open(name, std::ios::in);
if (!f)
printf("File does not exist, or inadequate permissions");
f.close();
使用输入/输出模式打开,以防止在计划执行写入操作时被截断:
std::fstream f;
f.open(name, std::ios::in | std::ios::out);
if (!f)
printf("Could not open file");
f.close();
默认情况下,这些是各个流的输入参数,但为了澄清起见,我已经明确显示了它们
在检查eof等的读/写操作期间,对的第一个答案看起来很有见地。good()
/bad())
只测试badbit
,它只包括一些,而且大部分是不可恢复的错误。要检查错误,您需要同时检查failbit
和badbit
。有关这些位的设置时间的更多详细信息,请参阅
要检查错误,请使用,它将同时检查failbit
和badbit
:
if (stream.fail()) { /* handle error ... */ }
std::string line;
while (std::getline(f, line)) {
// process line
}
if (!f && !f.eof()) {
std::cerr << std::strerror(errno) << std::endl;
}
C++流也会重载以返回!fail()
,因此您只需
if (!stream) { /* handle error ... */ }
然后,您可以从中获取最后一个错误,并使用以下命令将其转换为文本:
你只是想知道如何打开文件?还是也要读/写文件?@doctorlove是的,也要知道如何读/写文件会很好。我知道如何用(至少用C++)读/写文件我想抓住所有可能发生的坏事,根据错误的种类来抛出我自己的例外。我听说有些实现不会抛出异常。我想,这可能还不够。@ GHOMANDSD没有一个C++流函数抛出异常。必须在每一点上检查代码中的错误。请指正,恳求。se,如果我错了:我们必须检查
eof()
、fail()
和!operator()
成员函数,然后我们必须检查系统(可能使用predef
项目中的宏,然后我们必须使用errno
或GetLastError()检查代码)
取决于平台。我想在Linux上我可以使用man errno.h
来查看错误代码。Windows呢?我发现了,但它包含了很多代码,也许你知道我可以在哪里找到关于文件处理的代码?检查并提问。他们只确认你、MasterHD和我所说的一切d、 未能打开该文件可能并不意味着该文件不存在,可能是当前用户无权读/写该文件。此外,不需要标志,std::ios::in
是std::ifstream
的默认值,与std::fsstream
和std::ofstream
类似,正确的标志是默认值。注意:最好写“C:\\some\u folder\\some\u file.txt”而不是“C:\\some\u folder\\some\u file.txt”即使是在WIndows上。@ghostmansd花了我一段时间才意识到唯一的区别是删除下划线。DonetheIOS::in不是默认值,它是隐含的。这意味着即使您不将它提供给ifstream,您仍然可以得到它,因此编写它毫无用处。此外,我想补充一点,您不必调用open()另外,您可以使用这些参数初始化流。
std::string line;
while (std::getline(f, line)) {
// process line
}
if (!f && !f.eof()) {
std::cerr << std::strerror(errno) << std::endl;
}