ifstream 열기가 실패 할 때 오류 메시지를 얻는 방법
ifstream f;
f.open(fileName);
if ( f.fail() )
{
// I need error message here, like "File not found" etc. -
// the reason of the failure
}
오류 메시지를 문자열로 얻는 방법?
실패한 모든 시스템 호출은 errno
값을 업데이트합니다 .
따라서 ifstream
다음과 같은 것을 사용하여 열기가 실패 할 때 발생하는 일에 대한 자세한 정보를 얻을 수 있습니다 .
cerr << "Error: " << strerror(errno);
그러나 모든 시스템 호출이 전역 errno
값을 업데이트하기 때문에 다른 시스템 호출이의 실행 f.open
과 사용 사이에 오류를 트리거하는 경우 다중 스레드 응용 프로그램에서 문제가 발생할 수 있습니다 errno
.
POSIX 표준이있는 시스템에서 :
errno는 스레드 로컬입니다. 한 스레드에서 설정해도 다른 스레드의 값에는 영향을주지 않습니다.
편집 (댓글에 Arne Mertz 및 다른 사람들에게 감사) :
e.what()
처음에는 이것을 구현하는 더 C ++-idiomatically 올바른 방법으로 보였지만,이 함수에서 반환 된 문자열은 구현에 따라 다르며 (적어도 G ++의 libstdc ++에서)이 문자열에는 오류의 원인에 대한 유용한 정보가 없습니다.
실패시 스트림에서 예외를 throw하도록 할 수 있습니다.
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()
그러나별로 도움이되지 않는 것 같습니다.
- Win7, Embarcadero RAD Studio 2010에서 "ios_base :: failbit set"을
strerror(errno)
제공하고 "No such file or directory"를 제공합니다. - Ubuntu 13.04, gcc 4.7.3에서 "basic_ios :: clear"라는 예외가 표시됩니다 ( arne 덕분에 ).
에서 e.what()
작동하지 않는 경우 (표준화되지 않았으므로 오류에 대해 무엇을 알려 줄지 모르겠습니다) 다음을 사용해보십시오 std::make_error_condition
(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";
}
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.
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)
참고URL : https://stackoverflow.com/questions/17337602/how-to-get-error-message-when-ifstream-open-fails
'Programing' 카테고리의 다른 글
Knockout.js는 준 대형 데이터 세트에서 엄청나게 느립니다. (0) | 2020.09.14 |
---|---|
Git은 내 파일에서 왼쪽 HEAD 표시를 병합합니다. (0) | 2020.09.14 |
Google 앱 엔진 또는 아마존 웹 서비스 (0) | 2020.09.14 |
TypeError : 정의되지 않은 속성 'then'을 읽을 수 없습니다. (0) | 2020.09.14 |
Python : n 개의 목록을 만드는 가장 빠른 방법 (0) | 2020.09.14 |