C++中的cout、cerr、clog使用及說明
在C++編程里,cout、cerr和clog是標準庫提供的重要輸出流對象,在數(shù)據(jù)輸出方面發(fā)揮著關鍵作用。
一、cout:標準輸出流
cout 是 std::ostream 類的對象,其作用是向標準輸出設備(一般是控制臺)輸出數(shù)據(jù)。它和 C 語言中的 printf 函數(shù)類似,但 cout 具有類型安全和運算符重載的優(yōu)勢,使用起來更加方便。
1. 基本用法
借助 << 運算符,能把各種類型的數(shù)據(jù)輸出到 cout。
#include <iostream>
using namespace std;
int main() {
int num = 42;
double pi = 3.14159;
string name = "Alice";
cout << "Hello, World!" << endl;
cout << "Number: " << num << endl;
cout << "Pi: " << pi << endl;
cout << "Name: " << name << endl;
return 0;
}
輸出結果如下:
Hello, World! Number: 42 Pi: 3.14159 Name: Alice
2. 格式化輸出
通過操縱符(如 setw、setprecision 等)或者成員函數(shù)(像 width()、precision()),可以對輸出格式進行控制。
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
double value = 123.456789;
// 設置寬度和填充字符
cout << setw(10) << setfill('*') << 42 << endl; // 輸出:********42
// 設置精度
cout << fixed << setprecision(3) << value << endl; // 輸出:123.457
// 科學計數(shù)法
cout << scientific << value << endl; // 輸出:1.234568e+02
// 布爾值以文字形式輸出
cout << boolalpha << true << endl; // 輸出:true
return 0;
}
3. 鏈式輸出
<< 運算符返回的是對 cout 對象的引用,所以可以進行鏈式輸出。
int a = 10, b = 20; cout << "a = " << a << ", b = " << b << endl; // 輸出:a = 10, b = 20
4. 重定向輸出
可以利用 rdbuf() 函數(shù)對 cout 的輸出緩沖區(qū)進行重定向。
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream file("output.txt");
streambuf* oldBuf = cout.rdbuf(); // 保存原來的緩沖區(qū)
cout.rdbuf(file.rdbuf()); // 將輸出重定向到文件
cout << "This will be written to the file." << endl;
cout.rdbuf(oldBuf); // 恢復原來的輸出
cout << "This will be written to the console." << endl;
file.close();
return 0;
}
二、cerr:標準錯誤流
cerr 同樣是 std::ostream 類的對象,它專門用于輸出錯誤信息。和 cout 的主要區(qū)別在于,cerr 的輸出是不經(jīng)過緩沖的,會立即顯示在終端上。
1. 基本用法
當程序出現(xiàn)錯誤時,可使用 cerr 輸出錯誤信息。
#include <iostream>
using namespace std;
int main() {
ifstream file("nonexistent.txt");
if (!file.is_open()) {
cerr << "Error: Could not open file!" << endl;
return 1;
}
// 其他操作
return 0;
}
2. 無緩沖特性
cerr 的輸出不會被緩沖,這在需要立即顯示錯誤信息的場景下非常重要。
// 模擬一個長時間運行的進程
for (int i = 0; i < 1000000; ++i) {
if (i % 100000 == 0) {
cerr << "Processing iteration " << i << endl; // 立即顯示
}
// 處理邏輯
}
3. 重定向錯誤輸出
和 cout 一樣,cerr 的輸出也能被重定向。
ofstream errorFile("errors.log");
streambuf* oldBuf = cerr.rdbuf();
cerr.rdbuf(errorFile.rdbuf());
cerr << "This error will be logged to errors.log" << endl;
cerr.rdbuf(oldBuf); // 恢復
三、clog:標準日志流
clog 也是 std::ostream 類的對象,用于輸出日志信息。它和 cerr 的區(qū)別在于,clog 的輸出是經(jīng)過緩沖的。
1. 基本用法
clog 適用于記錄程序的執(zhí)行狀態(tài)等日志信息。
#include <iostream>
using namespace std;
void log(const string& message) {
clog << "[LOG] " << message << endl;
}
int main() {
log("Starting application...");
// 程序邏輯
log("Application terminated successfully.");
return 0;
}
2. 緩沖特性
clog 的輸出會先被存儲在緩沖區(qū)中,直到緩沖區(qū)滿或者遇到刷新操作。
clog << "This is a log message."; // 可能不會立即顯示 clog << flush; // 手動刷新緩沖區(qū)
3. 日志重定向
同樣可以對 clog 的輸出進行重定向。
ofstream logFile("app.log");
clog.rdbuf(logFile.rdbuf());
clog << "Logging to file..." << endl; // 寫入文件
四、三者的對比與選擇
| 特性 | cout | cerr | clog |
|---|---|---|---|
| 緩沖機制 | 有緩沖 | 無緩沖 | 有緩沖 |
| 默認輸出目標 | 標準輸出 | 標準錯誤 | 標準錯誤 |
| 典型應用場景 | 普通程序輸出 | 錯誤信息 | 日志記錄 |
| 是否可重定向 | 是 | 是 | 是 |
選擇建議:
- 當需要輸出程序的正常結果時,應使用
cout。 - 遇到錯誤情況,需要立即顯示錯誤信息時,要使用
cerr。 - 進行程序調(diào)試或者記錄執(zhí)行狀態(tài)等日志操作時,適合使用
clog。
五、高級應用場景
1. 自定義流緩沖區(qū)
可以通過繼承 streambuf 類來創(chuàng)建自定義的流緩沖區(qū)。
class MyBuffer : public streambuf {
protected:
int overflow(int c) override { //override C++11 特性,顯式聲明該函數(shù)重寫基類的虛函數(shù),提高代碼安全性
if (c != traits_type::eof()) { //獲取流特性中定義的 EOF(文件結束符)值
// 自定義處理邏輯
cout << "*" << static_cast<char>(c) << "*";
}
return traits_type::not_eof(c);
}
};
// 使用自定義緩沖區(qū)
MyBuffer buf;
ostream customOut(&buf);
customOut << "Test" << endl; // 輸出:*T*e*s*t*
2. 多線程環(huán)境下的輸出
在多線程環(huán)境中使用輸出流時,需要進行同步操作,以避免輸出混亂。
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
mutex coutMutex;
void worker(int id) {
lock_guard<mutex> lock(coutMutex);
cout << "Thread " << id << " is working." << endl;
}
int main() {
thread t1(worker, 1);
thread t2(worker, 2);
t1.join();
t2.join();
return 0;
}
3. 結合 RAII 管理流重定向
利用 RAII(資源獲取即初始化)技術,可以更安全地管理流重定向。
class StreamRedirect {
public:
StreamRedirect(ostream& stream, streambuf* newBuf)
: stream(stream), oldBuf(stream.rdbuf()) {
stream.rdbuf(newBuf);
}
~StreamRedirect() {
stream.rdbuf(oldBuf);
}
private:
ostream& stream;
streambuf* oldBuf;
};
// 使用示例
ofstream file("output.txt");
{
StreamRedirect redirect(cout, file.rdbuf());
cout << "Redirected output" << endl; // 寫入文件
} // 離開作用域時自動恢復
六、注意事項
性能考量:
- 無緩沖的輸出(如
cerr)會帶來一定的性能開銷,所以在性能敏感的場景中應當謹慎使用。 - 有緩沖的輸出(如
cout、clog)在頻繁刷新緩沖區(qū)時,也可能會影響性能。
線程安全:
- 標準輸出流本身并不是線程安全的,在多線程環(huán)境下使用時需要進行同步處理。
資源管理:
- 重定向流緩沖區(qū)后,要確保在適當?shù)臅r候恢復原來的緩沖區(qū)。
七、總結
- cout:是最常用的輸出流,適用于普通的程序輸出,輸出內(nèi)容會被緩沖。
- cerr:主要用于輸出錯誤信息,輸出不會被緩沖,能保證錯誤信息立即顯示。
- clog:適用于記錄日志,輸出會被緩沖,有助于提高性能。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
c++ TCHAR轉string導致中文缺失或亂碼問題及解決
這篇文章主要介紹了c++ TCHAR轉string導致中文缺失或亂碼問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08
vs code 配置c/c++環(huán)境的詳細教程(推薦)
這篇文章主要介紹了vs code 配置c/c++環(huán)境的詳細教程(推薦),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11

