用于 C++ 文件 IO 错误的 Try-Catch 块不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3629321/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 13:19:25  来源:igfitidea点击:

Try-Catch Block For C++ File-IO Errors Not Working

c++file-ioerror-handlingfilesystemstry-catch

提问by Jason R. Mick

I'm very new to the world of C++ error handling, but I was told here:
Checking for file existence in C++

我对 C++ 错误处理的世界很陌生,但有人告诉我:
在 C++ 中检查文件存在

...that the best way to checks for file existence was with a try-catch block. From my limited knowledge on the topic, this sounds like sound advice. I located this snippet of code:
http://www.java2s.com/Tutorial/Cpp/0240__File-Stream/Readafileintrycatchblock.htm

...检查文件存在的最佳方法是使用 try-catch 块。从我对该主题的有限了解来看,这听起来像是合理的建议。我找到了这段代码:
http://www.java2s.com/Tutorial/Cpp/0240__File-Stream/Readafileintrycatchblock.htm

#include <fstream>
#include <iostream>
using namespace std;

int main () 
{
  try{
      char buffer[256];
      ifstream myfile ("test.txt");

      while (! myfile.eof() )
      {
        myfile.getline (buffer,100);
        cout << buffer << endl;
      }
  }catch(...){
     cout << "There was an error !\n";
  }
  return 0;
}

...but when I compile it using

...但是当我编译它使用

g++ -Wall -pedantic -o test_prog main.cc

And run the program in a directory where test.txt does not exist, the prog keeps spitting out empty lines to the terminal. Can anyone figure out why?

并在 test.txt 不存在的目录中运行程序,程序不断向终端吐出空行。谁能弄清楚为什么?

Also is thisa good way to check for file existence for a file you actually want to open and read from (versus just something where your indexing a bunch of files and checking them over)?

也就是一个很好的方法来检查文件是否存在一些你真正要打开和读取(而不是只是一些在您的索引一堆文件,并检查他们交给)的文件?

Thanks!

谢谢!

回答by Artyom

In C++ iostreams do not throw exeptions by default. What you need is

在 C++ 中,iostreams 默认不抛出异常。你需要的是

ifstream myfile("test.txt");

if(myfile) {
   // We have one
}
else {
   // we dont
}

回答by dirkgently

By default the fstreamobjects do not throw. You need to use void exceptions ( iostate except );to set the exception behavior. You can fetch the current settings using iostate exceptions ( ) const;. Change your code just a bit:

默认情况下,fstream对象不会抛出。您需要使用void exceptions ( iostate except );来设置异常行为。您可以使用 获取当前设置iostate exceptions ( ) const;。稍微更改您的代码:

#include <fstream>
#include <iostream>
#include <stdexcept>
using namespace std;

int main () 
{
  try{
      char buffer[256];
      ifstream myfile ("test.txt");
      myfile.exceptions ( ifstream::eofbit | ifstream::failbit | ifstream::badbit );
      while (myfile)
      {
        myfile.getline (buffer,100);
        cout << buffer << endl;
      }
      myfile.close();

  }catch(std::exception const& e){
     cout << "There was an error: " << e.what() << endl;
  }
  return 0;
}

回答by Jerry Coffin

First of all, for the tryblock to do any good, you need to enable exceptions for the stream.

首先,try要使块发挥作用,您需要为流启用异常。

Second, a loop like:

其次,一个循环,如:

  while (! myfile.eof() )

Will lead to nothing but trouble, and you're seeing that here. The problem (in this case) is that when the file failed to open, eofwill never be signaled -- you can't/don't reach the end of the file because there isno file. Therefore, your loop runs forever, on an existentialist search for the end of a nonexistent file. Fix the loop, and things get better in a hurry:

只会导致麻烦,你在这里看到了。这个问题(在这种情况下)是,当文件打开失败,eof将永远不会被信号-你不能/不会因为没有达到文件的末尾没有文件。因此,您的循环将永远运行,以存在主义搜索不存在文件的结尾。修复循环,事情很快就会好起来:

 char buffer[256];
 ifstream myfile ("test.txt");

 while (myfile.getline(buffer,100))
 {
   cout << buffer << endl;
 }

While you're at it, a bit more fixing wouldn't hurt (unless you really meantto use less than half of the space you allocated for your buffer):

当你在做的时候,多一点修复不会有什么坏处(除非你真的打算使用不到你为缓冲区分配的空间的一半):

 char buffer[256];
 ifstream myfile ("test.txt");

 while (myfile.getline(buffer,sizeof(buffer)))
 {
   cout << buffer << endl;
 }

Or, of course, eliminate the problem entirely:

或者,当然,完全消除问题:

std::string buffer;
ifstream myfile("test.txt");
while (getline(myfile, buffer))
    cout << buffer << "\n";

Edit: note that noneof these (at least currently) depends on exceptions at all. They're all set up to write a line to the output if we succeeded in our attempt at reading a line from the input. If the file didn't open, the body of the loop simply won't execute, because we won't be able to read from a file that didn't open. If we want to print an error message telling the user that the file didn't open, we'd have to handle that separately from what's above. For example:

编辑:请注意,没有这些(至少目前)取决于在所有异常。如果我们成功地尝试从输入中读取一行,它们都被设置为向输出写入一行。如果文件没有打开,循环体就不会执行,因为我们将无法读取没有打开的文件。如果我们想打印一条错误消息告诉用户文件没有打开,我们必须与上面的内容分开处理。例如:

ifstream myfile("test.txt");

if (!myfile) {
    std::cerr << "File failed to open";
    return FAIL;
}

while (std::getline(myfile // ...