Try-Catch阻止C++文件IO错误不起作用

Jas*_*ick 6 c++ filesystems error-handling file-io try-catch

我对C++错误处理的世界很新,但我在这里被告知:
用C++检查文件是否存在

...检查文件存在的最佳方法是使用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;
}
Run Code Online (Sandbox Code Playgroud)

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

g++ -Wall -pedantic -o test_prog main.cc
Run Code Online (Sandbox Code Playgroud)

并且在不存在test.txt的目录中运行程序,编程不断向空中吐出空行.任何人都可以找出原因吗?

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

谢谢!

dir*_*tly 11

默认情况下,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;
}
Run Code Online (Sandbox Code Playgroud)


Art*_*yom 11

在C++中,iostreams默认情况下不会抛出exeptions.你需要的是什么

ifstream myfile("test.txt");

if(myfile) {
   // We have one
}
else {
   // we dont
}
Run Code Online (Sandbox Code Playgroud)


Jer*_*fin 8

首先,try要使块执行任何操作,您需要为流启用异常.

第二,循环如:

  while (! myfile.eof() )
Run Code Online (Sandbox Code Playgroud)

只会带来麻烦,你会在这里看到它.这个问题(在这种情况下)是,当文件打开失败,eof将永远不会被信号-你不能/不会因为没有达到文件的末尾没有文件.因此,你的循环永远运行,在存在主义搜索不存在的文件的末尾.修复循环,事情变得更好:

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

 while (myfile.getline(buffer,100))
 {
   cout << buffer << endl;
 }
Run Code Online (Sandbox Code Playgroud)

当你在它的时候,更多的修复不会受到伤害(除非你真的打算使用不到你为缓冲区分配的空间的一半):

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

 while (myfile.getline(buffer,sizeof(buffer)))
 {
   cout << buffer << endl;
 }
Run Code Online (Sandbox Code Playgroud)

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

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

编辑:请注意,这些(至少目前)都不依赖于例外.如果我们成功尝试从输入读取一行,那么它们都被设置为在输出中写一行.如果文件没有打开,循环体就不会执行,因为我们将无法读取未打开的文件.如果我们要打印一条错误消息告诉用户文件没有打开,我们必须单独处理上面的内容.例如:

ifstream myfile("test.txt");

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

while (std::getline(myfile // ...
Run Code Online (Sandbox Code Playgroud)