ifstream f;
f.open(fileName);
if ( f.fail() )
{
// I need error message here, like "File not found" etc. -
// the reason of the failure
}
Bagaimana cara mendapatkan pesan kesalahan sebagai string?
ifstream f;
f.open(fileName);
if ( f.fail() )
{
// I need error message here, like "File not found" etc. -
// the reason of the failure
}
Bagaimana cara mendapatkan pesan kesalahan sebagai string?
cerr << "Error code: " << strerror(errno); // Get some info as to why
sepertinya relevan dengan pertanyaan itu.
strerror(errno)
bekerja. Posting ini sebagai jawaban, saya akan menerimanya.
Jawaban:
Setiap panggilan sistem yang gagal memperbarui errno
nilai.
Dengan demikian, Anda dapat memperoleh lebih banyak informasi tentang apa yang terjadi ketika ifstream
pembukaan gagal dengan menggunakan sesuatu seperti:
cerr << "Error: " << strerror(errno);
Namun, sejak itu setiap panggilan sistem memperbarui nilai global errno
, Anda mungkin mengalami masalah dalam aplikasi multithread, jika panggilan sistem lain memicu kesalahan antara eksekusi f.open
dan penggunaan errno
.
Pada sistem dengan standar POSIX:
errno adalah thread-local; mengaturnya di satu utas tidak memengaruhi nilainya di utas lainnya.
Sunting (terima kasih kepada Arne Mertz dan orang lain di komentar):
e.what()
tampaknya pada awalnya lebih C ++ - cara yang secara idiomatis benar untuk mengimplementasikan ini, namun string yang dikembalikan oleh fungsi ini bergantung pada implementasi dan (setidaknya dalam libstdc ++ G ++) string ini tidak memiliki informasi yang berguna tentang alasan di balik kesalahan ...
e.what()
sepertinya tidak memberikan banyak informasi, lihat update jawaban saya.
errno
menggunakan penyimpanan lokal-utas pada sistem operasi modern. Namun, tidak ada jaminan bahwa fstream
fungsi tersebut tidak akan terhenti errno
setelah terjadi errno. Fungsi yang mendasari mungkin tidak diatur errno
sama sekali (panggilan sistem langsung di Linux, atau Win32). Ini tidak berfungsi pada banyak implementasi dunia nyata.
e.what()
selalu mencetak pesan yang sama " iostream stream error
"
warning C4996: 'strerror': This function or variable may be unsafe. Consider using strerror_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\string.h(168) : see declaration of 'strerror'
Anda dapat mencoba membiarkan aliran mengeluarkan pengecualian jika gagal:
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()
, bagaimanapun, sepertinya tidak terlalu membantu:
strerror(errno)
memberikan "Tidak ada file atau direktori seperti itu."Jika e.what()
tidak berhasil untuk Anda (saya tidak tahu apa yang akan dikatakannya tentang kesalahan tersebut, karena itu tidak terstandarisasi), coba gunakan std::make_error_condition
(hanya C ++ 11):
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";
}
strerror(errno)
diposting di komentar berfungsi dan sangat mudah digunakan. Saya pikir itu e.what
akan berhasil, karena errno
berhasil.
e.what()
akan strerror
kembali, dengan cara yang aman untuk thread. Keduanya mungkin bergantung pada platform.
exception.what()
. Semoga menjadi kesempatan yang baik untuk mempelajari kode sumber libstdc ++ :-)
basic_ios::clear
, tidak ada yang lain. Ini tidak terlalu membantu. Itu sebabnya saya tidak memposting;)
Mengikuti jawaban @Arne Mertz, mulai C ++ 11 std::ios_base::failure
mewarisi dari system_error
(lihat http://www.cplusplus.com/reference/ios/ios_base/failure/ ), yang berisi kode kesalahan dan pesan yang strerror(errno)
akan dikembalikan.
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;
}
Ini mencetak No such file or directory.
jika fileName
tidak ada.
iostream stream error
.
iostream error
. Pada kompiler apa Anda menguji ini? Apakah ada kompilator yang benar-benar memberikan alasan kegagalan yang dapat dibaca pengguna?
unspecified iostream_category error
.
Anda juga bisa melempar std::system_error
seperti yang ditunjukkan pada kode tes di bawah ini. Metode ini tampaknya menghasilkan keluaran yang lebih mudah dibaca daripada 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;
}
Contoh keluaran (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)