Fstream open error

ifstream f; f.open(fileName); if ( f.fail() ) { // I need error message here, like "File not found" etc. - // the reason of the failure } How to get error message as string?
ifstream f;
f.open(fileName);

if ( f.fail() )
{
    // I need error message here, like "File not found" etc. -
    // the reason of the failure
}

How to get error message as string?

László Papp's user avatar

László Papp

51.1k39 gold badges110 silver badges135 bronze badges

asked Jun 27, 2013 at 7:51

Alex F's user avatar

5

Every system call that fails update the errno value.

Thus, you can have more information about what happens when a ifstream open fails by using something like :

cerr << "Error: " << strerror(errno);

However, since every system call updates the global errno value, you may have issues in a multithreaded application, if another system call triggers an error between the execution of the f.open and use of errno.

On system with POSIX standard:

errno is thread-local; setting it in one thread does not affect its
value in any other thread.


Edit (thanks to Arne Mertz and other people in the comments):

e.what() seemed at first to be a more C++-idiomatically correct way of implementing this, however the string returned by this function is implementation-dependant and (at least in G++’s libstdc++) this string has no useful information about the reason behind the error…

S.R's user avatar

S.R

2,1911 gold badge21 silver badges32 bronze badges

answered Jun 27, 2013 at 9:02

Matthieu Rouget's user avatar

5

You could try letting the stream throw an exception on failure:

std::ifstream f;
//prepare f to throw if failbit gets set
std::ios_base::iostate exceptionMask = f.exceptions() | std::ios::failbit;
f.exceptions(exceptionMask);

try {
  f.open(fileName);
}
catch (std::ios_base::failure& e) {
  std::cerr << e.what() << 'n';
}

e.what(), however, does not seem to be very helpful:

  • I tried it on Win7, Embarcadero RAD Studio 2010 where it gives «ios_base::failbit set» whereas strerror(errno) gives «No such file or directory.»
  • On Ubuntu 13.04, gcc 4.7.3 the exception says «basic_ios::clear» (thanks to arne)

If e.what() does not work for you (I don’t know what it will tell you about the error, since that’s not standardized), try using std::make_error_condition (C++11 only):

catch (std::ios_base::failure& e) {
  if ( e.code() == std::make_error_condition(std::io_errc::stream) )
    std::cerr << "Stream error!n"; 
  else
    std::cerr << "Unknown failure opening file.n";
}

Community's user avatar

answered Jun 27, 2013 at 8:19

Arne Mertz's user avatar

Arne MertzArne Mertz

23.9k2 gold badges51 silver badges89 bronze badges

9

Following on @Arne Mertz’s answer, as of C++11 std::ios_base::failure inherits from system_error (see http://www.cplusplus.com/reference/ios/ios_base/failure/), which contains both the error code and message that strerror(errno) would return.

std::ifstream f;

// Set exceptions to be thrown on failure
f.exceptions(std::ifstream::failbit | std::ifstream::badbit);

try {
    f.open(fileName);
} catch (std::system_error& e) {
    std::cerr << e.code().message() << std::endl;
}

This prints No such file or directory. if fileName doesn’t exist.

answered Apr 14, 2016 at 4:35

rthur's user avatar

rthurrthur

1,4361 gold badge15 silver badges15 bronze badges

5

You can also throw a std::system_error as shown in the test code below. This method seems to produce more readable output than f.exception(...).

#include <exception> // <-- requires this
#include <fstream>
#include <iostream>

void process(const std::string& fileName) {
    std::ifstream f;
    f.open(fileName);

    // after open, check f and throw std::system_error with the errno
    if (!f)
        throw std::system_error(errno, std::system_category(), "failed to open "+fileName);

    std::clog << "opened " << fileName << std::endl;
}

int main(int argc, char* argv[]) {
    try {
        process(argv[1]);
    } catch (const std::system_error& e) {
        std::clog << e.what() << " (" << e.code() << ")" << std::endl;
    }
    return 0;
}

Example output (Ubuntu w/clang):

$ ./test /root/.profile
failed to open /root/.profile: Permission denied (system:13)
$ ./test missing.txt
failed to open missing.txt: No such file or directory (system:2)
$ ./test ./test
opened ./test
$ ./test $(printf '%0999x')
failed to open 000...000: File name too long (system:36)

answered Jun 30, 2018 at 22:27

ɲeuroburɳ's user avatar

ɲeuroburɳɲeuroburɳ

6,9103 gold badges23 silver badges22 bronze badges

The std::system_error example above is slightly incorrect. std::system_category() will map the error codes from system’s native error code facility. For *nix, this is errno. For Win32, it is GetLastError(). ie, on Windows, the above example will print

failed to open C:pathtoforbidden: The data is invalid

because EACCES is 13 which is the Win32 error code ERROR_INVALID_DATA

To fix it, either use the system’s native error code facility, eg on Win32

throw new std::system_error(GetLastError(), std::system_category(), "failed to open"+ filename);

Or use errno and std::generic_category(), eg

throw new std::system_error(errno, std::generic_category(), "failed to open"+ filename);

answered Feb 16, 2021 at 17:54

Daniel Cranford's user avatar

void open( const char* filename,
           std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out );

(1)

void open( const std::filesystem::path::value_type* filename,
           std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out );

(2) (since C++17)

void open( const std::string& filename,                                  
           std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out );

(3) (since C++11)

void open( const std::filesystem::path& filename,                                  
           std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out );

(4) (since C++17)

Opens and associates the file with name filename with the file stream.

Calls clear() on success. Calls setstate(failbit) on failure.

1,2) Effectively calls rdbuf()>open(filename, mode) (see std::basic_filebuf::open for the details on the effects of that call). Overload (2) is only provided if std::filesystem::path::value_type is not char. (since C++17)

3,4) Effectively calls (1,2) as if by open(filename.c_str(), mode).

[edit] Parameters

filename the name of the file to be opened
mode specifies stream open mode. It is a BitmaskType, the following constants are defined:

Constant Explanation
app seek to the end of stream before each write
binary open in binary mode
in open for reading
out open for writing
trunc discard the contents of the stream when opening
ate seek to the end of stream immediately after open
noreplace (C++23) open in exclusive mode

[edit] Return value

(none)

[edit] Example

#include <string>
#include <fstream>
#include <iostream>
 
int main()
{
    std::string filename = "example.123";
 
    std::fstream fs;
    fs.open(filename);
 
    if (!fs.is_open())
    {
        fs.clear();
        fs.open(filename, std::ios::out); // create file
        fs.close();
        fs.open(filename);
    }
 
    std::cout << std::boolalpha;
    std::cout << "fs.is_open() = " << fs.is_open() << 'n';
    std::cout << "fs.good() = " << fs.good() << 'n';
}

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 22 C++98 it was unclear how error state changes upon a successful open the error state is unchanged
LWG 409 C++98 the error state was unchanged upon a successful open it is cleared[1]
  1. The resolution of LWG issue #22 is overriden.

[edit] See also

checks if the stream has an associated file
(public member function) [edit]
closes the associated file
(public member function) [edit]
opens a file and configures it as the associated character sequence
(public member function of std::basic_filebuf<CharT,Traits>) [edit]

It’s quite common that errors may occur during file operations. There may have different reasons for arising errors while working with files. The following are the common problems that lead to errors during file operations.

  • When trying to open a file for reading might not exist.
  • When trying to read from a file beyond its total number of characters.
  • When trying to perform a read operation from a file that has opened in write mode.
  • When trying to perform a write operation on a file that has opened in reading mode.
  • When trying to operate on a file that has not been open.

During the file operations in C++, the status of the current file stream stores in an integer flag defined in ios class. The following are the file stream flag states with meaning.

Flag Bit Meaning
badbit 1 when a fatal I/O error has occurred, 0 otherwise.
failbit 1 when a non-fatal I/O error has occurred, 0 otherwise
goodbit 1 when no error has occurred, 0 otherwise
eofbit 1 when end-of-file is encountered, 0 otherwise.

We use the above flag bits to handle the errors during the file operations.


Error Handling During the File Operations in C++

The C++ programming language provides several built-in functions to handle errors during file operations. The file error handling

The following are the built-in functions to handle file errors.

Function Return Value
int bad() It returns a non-zero (true) value if an invalid operation is attempted or an unrecoverable error has occurred. Returns zero if it may be possible to recover from any other error reported and continue operations.
int fail( ) It returns a non-zero (true) value when an input or output operation has failed.
int good() It returns a non-zero (true) value when no error has occurred; otherwise returns zero (false).
int eof( ) It returns a non-zero (true) value when end-of-file is encountered while reading; otherwise returns zero (false).

int bad( )

The bad( ) function returns a non-zero (true) value if an invalid operation is attempted or an unrecoverable error has occurred. Returns zero if it may be possible to recover from any other error reported and continue operations.

Let’s look at the following code.

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    fstream file;
    file.open("my_file.txt", ios::out);

    string data;

    file >> data;

    if(!file.bad()){
        cout << "Operation not success!!!" << endl;
        cout << "Status of the badbit: " << file.bad() << endl;
    }
    else {
        cout << "Data read from file - " << data << endl;
    }

    return 0;
}

switch statement example program in c++

int fail( )

The fail( ) function returns a non-zero value when an input or output operation has failed.

Let’s look at the following code.

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    fstream file;
    file.open("my_file.txt", ios::out);

    string data;

    file >> data;

    if(file.fail()){
        cout << "Operation not success!!!" << endl;
        cout << "Status of the failbit: " << file.fail() << endl;
    }
    else {
        cout << "Data read from file - " << data << endl;
    }

    return 0;
}

switch statement example program in c++

int eof( )

The eof( ) function returns a non-zero (true) value when end-of-file is encountered while reading; otherwise returns zero (false).

Let’s look at the following code.

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    fstream file;
    file.open("my_file.txt", ios::in);

    string data;

    while(!file.eof()){
        file >> data;
        cout << "data read: " << data << " | eofbit: " << file.eof() << endl;
    }

    return 0;
}

switch statement example program in c++

int good( )

The good( ) function returns a non-zero (true) value when no error has occurred; otherwise returns zero (false).

Let’s look at the following code.

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    fstream file;
    file.open("my_file.txt", ios::in);

    cout << "goodbit: " << file.good() << endl;

    string data;

    cout << endl << "Data read from file:" << endl;
    while(!file.eof()){
        file >> data;
        cout << data << " ";
    }
    cout << endl;

    return 0;
}

switch statement example program in c++

int clear( )

The clear( ) function used to reset the error state so that further operations can be attempted.

Использование Visual Studio 2012 & со свойствами проекта:

  1. Свойства конфигурации: Общие: Проект по умолчанию: Набор символов:
    Не установлен
  2. Свойства конфигурации: C ++: Язык: обрабатывать WChar_t как встроенный
    Тип: нет

Я использую ofstream со следующим фрагментом кода:
Примечание: путь «C: data» действителен для этого примера

ofstream fexp;
fexp.open("c:datatest.txt", ios::out|ios::binary|ios::app);
fexp << "writing some text to file with append in binary" << endl;
fexp.flush();
fexp.close();

Если файл отсутствует в каталоге, файл будет открыт, текст будет записан и т. Д. Если файл уже существовал, файл не открывается, не записывается и т. Д. Не возникло никаких исключений и не был найден код ошибки (в errno ). При отладке внутреннего метода open () я обнаружил некоторое внутреннее открытие
звонки пытались скопировать строку имени файла в тип wchar_t и закрылись с внутренней ошибкой 13 (поиск констант MS = Open Aborted).

MBCS устарела, поэтому я не хочу устанавливать это. Единственный другой вариант — это Unicode, который нарушает половину моих изменений. Почему я не могу использовать библиотеку std io ?? !!!

Что еще страннее, у меня была некоторая часть этой работы со вторым переключателем на нет с 1-м набором MBCS. Несмотря на то, что код работал во многих местах, связанных с графическими интерфейсами, такими как CEdit, у меня было много лишнего кода для преобразования из CString в строку, если бы мне пришлось. Если в сущности представление CString представляет собой const char *, что несколько близко к LPCTSTR (не совсем). Это «ДОЛЖЕН«быть несколько»ПРОСТО«конвертировать из CString в строку. Это не потому, что ненужный осложнения переключений между UTF-8 и UTF-16, которыми я не занимаюсь. Я хочу, чтобы мой символ был СТРОГО 1 БАЙТ.

Какой самый близкий путь через это безумие? Должен ли я вернуться обратно к MBCS (хотя и устарел) и изменить все методы контейнера с
GetWindowText () для GetWindowTextA () например или отказаться от использования потоков в Visual Studio, или что ???

Пожалуйста, посоветуйте, если можете … Любая помощь будет принята с благодарностью. Благодарю.

Бешеный пес

ps: Пожалуйста, не беспокойтесь, чтобы превратить меня в полную среду Wide в моем коде, когда мой продукт не будет продаваться в Азии или Аравии.

pps: последнее замечание, которое я получил, потому что я заметил, что моя первоначальная установка Visual Studio 2012 по умолчанию установлена ​​на MBCS.

0

Решение

Как уже отмечали другие, ваша проблема вызвана побегом ,

"c:datatest.txt"

Должно быть

"c:\data\test.txt"

Вы можете узнать больше о escape-последовательностях Вот.

Чтобы избежать путаницы, вы можете использовать / вместо в ваших файловых путях.

"C:/data/test.txt"

1

Другие решения

Тем, кто все еще следит за этим, через два с половиной дня я понял, что происходит. Извините за задержку в публикации этого. На самом деле, я полностью забыл об этом.

Это был случай разрешения доступа к родительскому каталогу. Не просто регулярное отрицание. Я имею в виду особый отказ в открытии файла, чтобы добавить к нему (открыть с добавлением). Обычно вы даже не видите эти настройки, если не перейдете в расширенный режим на вкладке безопасности окна свойств файла или каталогов. Даже тогда вы должны сделать пару дополнительных шагов. Поэтому в каталоге над каталогом, в котором находился мой файл, был установлен этот параметр (по какой-то невероятной причине). Тем не менее, я
проверил все три метода работы сейчас (fopen(), CFile.open(), stream.open()).

Спасибо за все идеи, я многому научился, чего раньше не знал. Некоторые идеи были великолепны.

Бешеный пес

0

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Fspy import error trying to import an fspy project with no camera parameters
  • Fspuip fail to add tray icon как исправить
  • Fshx runtime error
  • Fsgame ltx чистое небо ошибка скачать
  • Fsck failed with error code 4

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии