Блок Try-Catch для ошибок файлового ввода-вывода C ++ не работает - PullRequest
6 голосов
/ 02 сентября 2010

Я очень новичок в мире обработки ошибок 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;
}

... но когда я скомпилировал его с помощью

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

и запустил программу в каталогетам, где test.txt не существует, программа продолжает выплевывать пустые строки в терминал.Может кто-нибудь выяснить, почему?

Также это хороший способ проверить существование файла для файла, который вы действительно хотите открыть и прочитать (по сравнению с чем-то, где вы индексируете множествофайлы и проверка их)?

Спасибо!

Ответы [ 3 ]

11 голосов
/ 02 сентября 2010

В C ++ iostreams по умолчанию не генерируют исключения.Что вам нужно, это

ifstream myfile("test.txt");

if(myfile) {
   // We have one
}
else {
   // we dont
}
11 голосов
/ 02 сентября 2010

По умолчанию 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;
}
8 голосов
/ 02 сентября 2010

Прежде всего, чтобы блок try приносил какую-либо пользу, необходимо включить исключения для потока.

Во-вторых, цикл типа:

  while (! myfile.eof() )

приведетничего, кроме неприятностей, и вы видите это здесь.Проблема (в данном случае) в том, что когда файл не открывается, eof никогда не будет сигнализироваться - вы не можете / не можете достичь конца файла, потому что - это файла нет,Следовательно, ваш цикл выполняется вечно при поиске экзистенциалистом конца несуществующего файла.Исправьте петлю, и все станет лучше в спешке:

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

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

Пока вы это делаете, немного больше исправлений не повредит (если вы действительно не хотели использовать меньшеполовины пространства, выделенного для буфера):

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

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

Или, конечно, полностью устранить проблему:

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

Редактировать: обратите внимание, что нет из них (по крайней мере, в настоящее время) зависит от исключений вообще.Все они настроены на запись строки в вывод, если мы преуспели в нашей попытке прочитать строку из ввода.Если файл не открылся, тело цикла просто не будет выполнено, потому что мы не сможем читать из файла, который не открылся.Если мы хотим напечатать сообщение об ошибке, сообщающее пользователю, что файл не открылся, мы должны обработать это отдельно от того, что описано выше.Например:

ifstream myfile("test.txt");

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

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