ifstream f;
f.open(fileName);
if ( f.fail() )
{
// I need error message here, like "File not found" etc. -
// the reason of the failure
}
Hata mesajı string olarak nasıl alınır?
ifstream f;
f.open(fileName);
if ( f.fail() )
{
// I need error message here, like "File not found" etc. -
// the reason of the failure
}
Hata mesajı string olarak nasıl alınır?
cerr << "Error code: " << strerror(errno); // Get some info as to why
soruyla alakalı görünüyor.
strerror(errno)
çalışır. Bunu cevap olarak gönder, kabul edeceğim.
Yanıtlar:
Başarısız olan her sistem çağrısı errno
değeri günceller .
Böylece, aşağıdakiler gibi bir ifstream
şey kullanarak bir açık başarısız olduğunda ne olacağı hakkında daha fazla bilgi edinebilirsiniz :
cerr << "Error: " << strerror(errno);
Ancak, her sistem çağrısı genel errno
değeri güncellediğinden, çok iş parçacıklı bir uygulamada sorun yaşayabilirsiniz, eğer başka bir sistem çağrısı işleminin yürütülmesi f.open
ile errno
.
POSIX standardına sahip sistemde:
errno iş parçacığı yereldir; bunu bir iş parçacığında ayarlamak, diğer iş parçacığındaki değerini etkilemez.
Düzenleme (Arne Mertz ve yorumlardaki diğer insanlara teşekkürler):
e.what()
ilk bakışta daha C ++ gibi görünüyordu - bunu uygulamanın deyimsel olarak doğru yolu, ancak bu işlev tarafından döndürülen dize uygulamaya bağlıdır ve (en azından G ++ 'ın libstdc ++' da) bu dizge, hatanın arkasındaki neden hakkında hiçbir yararlı bilgiye sahip değildir ...
e.what()
fazla bilgi vermiyor, cevabımın güncellemelerine bakın.
errno
modern işletim sistemlerinde iş parçacığı yerel depolamayı kullanır. Ancak, bir hata oluştuktan sonra fstream
işlevlerin bozulmayacağının garantisi yoktur errno
. Temel işlevler hiç ayarlanmayabilir errno
(Linux veya Win32'de doğrudan sistem çağrıları). Bu pek çok gerçek dünya uygulamasında işe yaramaz.
e.what()
hep aynı mesajı "yazdırır 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'
Akışın hata durumunda bir istisna atmasına izin vermeyi deneyebilirsiniz:
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()
ancak çok yardımcı görünmüyor:
strerror(errno)
"Böyle bir dosya veya dizin yok."Eğer e.what()
işi sizin için değil, kullanmayı deneyin (bunu standardize değil çünkü, hata hakkında söyleyecektir bilmiyorum) std::make_error_condition
(C ++ 11 için):
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)
yorumlarda yayınlandı ve kullanımı çok basit. Çalıştığından e.what
beri errno
işe yarayacağını düşünüyorum .
e.what()
, iş parçacığı güvenli strerror
bir şekilde geri dönecek. Her ikisi de muhtemelen platforma bağlı olacaktır.
exception.what()
. Libstdc ++ kaynak koduna dalmak için iyi bir fırsat olabilir :-)
basic_ios::clear
, başka bir şey yok. Bu gerçekten yardımcı olmuyor. Bu yüzden göndermedim;)
@Arne Mertz'in cevabını takiben, C ++ 11'den std::ios_base::failure
itibaren system_error
(bkz. Http://www.cplusplus.com/reference/ios/ios_base/failure/ ), hem hata kodunu hem de strerror(errno)
geri dönecek mesajı içeren .
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;
}
Bu No such file or directory.
, fileName
yoksa yazdırılır .
iostream stream error
.
iostream error
. Bunu hangi derleyicide test ettiniz? Herhangi bir derleyici gerçekten hata için kullanıcı tarafından okunabilir bir neden sağlıyor mu?
unspecified iostream_category error
.
f.open(fileName)
türden bir istisna atar . İstisna, catch bloğu tarafından yakalanır. Catch bloğu içinde, türden bir nesne döndüren çağırır . Sınıf tarafından tanımlı hata kodları olan platforma bağımlı --ie, ve her iki dönüş platforma göre değerleri. std::ios_base::failure
std::system_error
e.code()
std::ios_base::failure::code()
std::error_code
std::error_code
e.code().message()
e.code().value()
std::system_error
Aşağıdaki test kodunda gösterildiği gibi bir de atabilirsiniz . Bu yöntem, daha okunabilir çıktı üretiyor gibi görünüyor 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;
}
Örnek çıktı (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)