在 Linux 环境下使用 C++ 开发时,有效的错误处理是编写健壮软件的关键。以下是一些主要的错误处理技术和方法:
虽然 C++ 提供了更现代的错误处理机制,但在与 Linux 系统 API 交互时仍经常使用 C 风格错误处理:
#include <cerrno> // 包含 errno 宏
#include <cstring> // 包含 strerror
int fd = open("file.txt", O_RDONLY);
if (fd == -1) {
// 使用 errno 获取错误代码
std::cerr << "打开文件失败: " << strerror(errno) << std::endl;
// 或者使用 perror
perror("打开文件失败");
}
C++ 提供了更结构化的异常处理机制:
#include <stdexcept>
#include <system_error> // C++11 引入
void processFile(const std::string& filename) {
std::ifstream file(filename);
if (!file) {
// 使用系统错误码构造异常
throw std::system_error(errno, std::system_category(), filename);
}
// 或者抛出自定义异常
if (someErrorCondition) {
throw std::runtime_error("自定义错误信息");
}
// 处理文件...
}
int main() {
try {
processFile("data.txt");
} catch (const std::system_error& e) {
std::cerr << "系统错误: " << e.what() << " (code: " << e.code() << ")\n";
} catch (const std::exception& e) {
std::cerr << "标准异常: " << e.what() << "\n";
} catch (...) {
std::cerr << "未知异常\n";
}
}
#include <system_error>
std::error_code ec;
int fd = open("file.txt", O_RDONLY);
if (fd == -1) {
ec = std::error_code(errno, std::system_category());
if (ec == std::errc::no_such_file_or_directory) {
// 处理特定错误
}
}
// 需要支持 C++23 或使用类似实现
std::expected<int, std::error_code> openFile(const std::string& path) {
int fd = open(path.c_str(), O_RDONLY);
if (fd == -1) {
return std::unexpected(std::error_code(errno, std::system_category()));
}
return fd;
}
// 使用
auto result = openFile("data.txt");
if (!result) {
std::cerr << "错误: " << result.error().message() << "\n";
} else {
int fd = *result;
// 使用文件描述符...
}
#include <csignal>
#include <cstdlib>
void signalHandler(int sig) {
std::cerr << "接收到信号: " << sig << std::endl;
// 清理资源
exit(EXIT_FAILURE);
}
int main() {
signal(SIGSEGV, signalHandler); // 段错误
signal(SIGFPE, signalHandler); // 算术错误
// ... 其他信号
}
class FileDescriptor {
int fd_;
public:
explicit FileDescriptor(const char* path) : fd_(open(path, O_RDONLY)) {
if (fd_ == -1) {
throw std::system_error(errno, std::system_category(), "无法打开文件");
}
}
~FileDescriptor() {
if (fd_ != -1) {
close(fd_);
}
}
// 禁止拷贝
FileDescriptor(const FileDescriptor&) = delete;
FileDescriptor& operator=(const FileDescriptor&) = delete;
// 允许移动
FileDescriptor(FileDescriptor&& other) noexcept : fd_(other.fd_) {
other.fd_ = -1;
}
// 其他方法...
};
// 使用
try {
FileDescriptor fd("data.txt");
// 使用 fd...
} catch (const std::system_error& e) {
// 处理错误
}
#include <syslog.h> // Linux 系统日志
void logError(const std::string& message) {
// 写入系统日志
openlog("myapp", LOG_PID | LOG_CONS, LOG_USER);
syslog(LOG_ERR, "%s", message.c_str());
closelog();
// 同时输出到标准错误
std::cerr << "错误: " << message << std::endl;
}
通过结合这些技术,您可以构建健壮的 Linux C++ 应用程序,能够有效地检测、报告和处理各种错误条件。