std::cerr是ISO C++标准错误输出流

本文介绍了C++中标准错误输出流std::cerr的概念及其与标准输出流std::cout的区别。cerr保证每次输出后自动刷新,常用于显示错误信息;而cout则默认缓冲输出。通过示例展示了二者在输出行为上的不同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1概念




std::cerr是ISO C++标准错误输出流,对应于ISO C标准库的stderr。
与std::cout不同,ISO C++要求当cerr被初始化后,cerr.flags() & unitbuf非零(保证流在每次输出操作后被刷新),且cerr.tie()返回&cout。[1] 即cerr默认和cout同步但无缓冲。



2cerr与cout的区别




cout对应于标准输出流,默认情况下是显示器。这是一个被缓冲的输出,可以被重定向。
cerr对应标准错误流,用于显示错误消息。默认情况下被关联到标准输出流,但它不被缓冲,也就说错误消息可以直接发送到显示器,而无需等到缓冲区或者新的换行符时,才被显示。一般情况下不被重定向。
例如下面代码编译后生成test.exe
// test.cpp
#include <iostream>
using namespace std;
int main()
{
cout << "hello world---cout" << endl ;
cerr << "hello world---cerr" << endl ;
return 0;
}
在命令行模式下键入下面的命令:   
test >>cout.txt
运行结果是:
在生成的cout.txt文件中输出了"hello world---cout" ,
同时在显示器上输出了"hello world---cerr" ,
也就是说cout的输出可以重定向到一个文件中,而cerr必须输出在显示器上。




3为什么要用cerr




比如,你的程序遇到调用栈用完了的威胁(无限,没有出口的递归)。
你说,你到什么地方借内存,存放你的错误信息?
所以有了cerr。其目的,就是在你最需要它的紧急情况下,还能得到输出功能的支持。 缓冲区的目的,就是减少刷屏的次数——比如,你的程序输出圣经中的一篇文章。不带缓冲的话,就会每写一个字母,就输出一个字母,然后刷屏。有了缓冲,你将看到若干句子“同时”就出现在了屏幕上(由内存翻新到显存,然后刷新屏幕)。
上面是所有的数据请用下面的代码更改#include <iostream> #include <fstream> #include <sstream> #include <string> #include <vector> #include <regex> struct LogEntry { std::string time; int V = -1, C = -1; int L_Pump = -1, R_Pump = -1; bool isComplete() const { return !time.empty() && V != -1 && C != -1 && L_Pump != -1 && R_Pump != -1; } }; // 修复字段粘连错误,如 L_Pump188 → L_Pump:188 std::string fixMalformedLine(const std::string& line) { std::string fixed = line; std::regex malformed(R"((\bL_Pump|\bR_Pump|\bV|\bC)(\d+))"); // 匹配类似 L_Pump123 fixed = std::regex_replace(fixed, malformed, "$ 1:$ 2"); return fixed; } std::vector<LogEntry> parseLogFile(const std::string& filename) { std::ifstream file(filename); std::string line; std::vector<LogEntry> entries; LogEntry currentEntry; std::regex timeRegex(R"(\b\d{4}[/\-]\d{1,2}[/\-]\d{1,2}\s+\d{2}:\d{2}(?::\d{2})?\b)"); std::regex vRegex(R"(\bV\s*[:=]\s*(\d+))"); std::regex cRegex(R"(\bC\s*[:=]\s*(\d+))"); std::regex lPumpRegex(R"(\bL_Pump\s*[:=]\s*(\d+))"); std::regex rPumpRegex(R"(\bR_Pump\s*[:=]\s*(\d+))"); while (std::getline(file, line)) { line = fixMalformedLine(line); // 修复粘连错误 std::smatch match; // 检查是否是新时间戳 if (std::regex_search(line, match, timeRegex)) { if (!currentEntry.time.empty()) { entries.push_back(currentEntry); } currentEntry = {}; currentEntry.time = match.str(); } // 提取字段 if (std::regex_search(line, match, vRegex)) { try { currentEntry.V = std::stoi(match[1]); } catch (...) {} } if (std::regex_search(line, match, cRegex)) { try { currentEntry.C = std::stoi(match[1]); } catch (...) {} } if (std::regex_search(line, match, lPumpRegex)) { try { currentEntry.L_Pump = std::stoi(match[1]); } catch (...) {} } if (std::regex_search(line, match, rPumpRegex)) { try { currentEntry.R_Pump = std::stoi(match[1]); } catch (...) {} } } // 保存最后一条日志 if (!currentEntry.time.empty()) { entries.push_back(currentEntry); } return entries; } void saveToCSV(const std::vector<LogEntry>& entries, const std::string& csvFilename) { std::ofstream outFile(csvFilename); if (!outFile.is_open()) { std::cerr << "❌ 无法打开文件: " << csvFilename << std::endl; return; } outFile << "时间,V,C,L_Pump,R_Pump\n"; for (const auto& entry : entries) { outFile << entry.time << "," << entry.V << "," << entry.C << "," << entry.L_Pump << "," << entry.R_Pump << "\n"; } outFile.close(); } int main() { std::string logFilename = "C:\\Users\\A\\Desktop\\input.txt"; std::string csvFilename = "C:\\Users\\A\\Desktop\\output.csv"; std::cout << "🔧 正在尝试解析日志文件..." << std::endl; auto entries = parseLogFile(logFilename); std::cout << "🔍 解析完成,共找到 " << entries.size() << " 条记录。" << std::endl; if (entries.empty()) { std::cerr << "⚠️ 没有有效数据被解析,请检查日志格式或文件内容。" << std::endl; return 1; } std::cout << "💾 正在写入 CSV 文件: " << csvFilename << std::endl; saveToCSV(entries, csvFilename); std::cout << "✅ CSV 文件已成功生成!" << std::endl; return 0; }
最新发布
06-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值