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 whysepertinya relevan dengan pertanyaan itu.
strerror(errno)bekerja. Posting ini sebagai jawaban, saya akan menerimanya.
Jawaban:
Setiap panggilan sistem yang gagal memperbarui errnonilai.
Dengan demikian, Anda dapat memperoleh lebih banyak informasi tentang apa yang terjadi ketika ifstreampembukaan 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.opendan 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.
errnomenggunakan penyimpanan lokal-utas pada sistem operasi modern. Namun, tidak ada jaminan bahwa fstreamfungsi tersebut tidak akan terhenti errnosetelah terjadi errno. Fungsi yang mendasari mungkin tidak diatur errnosama 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.whatakan berhasil, karena errnoberhasil.
e.what()akan strerrorkembali, 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::failuremewarisi 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 fileNametidak 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_errorseperti 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)