【程序】
#include <fstream>
#include <iostream>
#include <Windows.h>
#define RDBUF_LEN 200
using namespace std;
ostream &operator << (ostream &os, const wchar_t *wstr)
{
if (os == cout)
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wstr, wcslen(wstr), NULL, NULL); // 輸出到屏幕上
else
{
// 此時wstr是UTF-16編碼
// 將其轉換為UTF-8編碼後寫入文件
int n = WideCharToMultiByte(CP_UTF8, NULL, wstr, -1, NULL, NULL, NULL, NULL);
char *p = new char[n];
WideCharToMultiByte(CP_UTF8, NULL, wstr, -1, p, n, NULL, NULL);
os.write(p, n - 1);
delete[] p;
}
return os;
}
ostream &operator << (ostream &os, wstring &ws)
{
os << ws.c_str();
return os;
}
istream &operator >> (istream &is, wstring &ws)
{
int n = 0;
wchar_t *wp;
if (is == cin)
{
/* 從控制台中輸入一行字符串 */
bool complete = false;
DWORD dwRead; // 實際讀到的字符個數
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
wp = NULL;
do
{
/* 分次循環讀取, 直到遇到換行符 */
wp = (wchar_t *)realloc(wp, (n + RDBUF_LEN + 2) * sizeof(wchar_t)); // 分配內存時始終為\r\n預留空間
ReadConsoleW(hInput, wp + n, RDBUF_LEN + 2, &dwRead, NULL);
if (wp[n + dwRead - 2] == '\r')
{
wp[n + dwRead - 2] = '\0'; // 把\r換成\0, 並結束讀取
complete = true;
// 注意: 當本次只讀到\n一個字符時, wp[n + dwRead - 2]指向上一次讀到的那一段的最後一個字符, 且一定是\r
// 例如: [abc][de\r][\n ], 此時RDBUF_LEN=1, 第二次讀的時候n=3, dwRead=3, wp[3+3-2]=wp[4]是e而不是\r, 所以繼續
// 第三次讀的時候n=6, dwRead=1, wp[6+1-2]=wp[5]恰好是\r, 因此將\r替換成\0並退出循環
}
else
n += dwRead;
} while (!complete);
ws = wp;
free(wp);
}
else
{
/* 從文件中讀取一行字符串 */
streampos start_pos = is.tellg(); // 記錄開始讀取的位置
char ch;
while (ch = is.get(), !is.eof() && ch != '\r' && ch != '\n')
n++; // 尋找換行符或文件結束符出現的位置
is.seekg(start_pos); // 回到開始位置
// 讀取這一部分內容
char *p = new char[n + 1];
is.read(p, n);
p[n] = '\0';
// 使文件位置指針跳過換行符
while (ch = is.get(), !is.eof() && (ch == '\r' || ch == '\n'));
if (!is.eof())
is.seekg(-1, ios::cur);
// 轉換成UTF-16編碼
n = MultiByteToWideChar(CP_UTF8, NULL, p, -1, NULL, NULL);
wp = new wchar_t[n];
MultiByteToWideChar(CP_UTF8, NULL, p, -1, wp, n);
delete[] p;
ws = wp;
delete[] wp;
}
return is;
}
int main(void)
{
// 從控制台中輸入Unicode字符串
wstring wstr;
cout << L"請輸入一段文字: ";
cin >> wstr;
// 打開文件並寫入Unicode字符串
ofstream file("file.txt");
if (!file.is_open())
{
cout << L"文件打開失敗" << endl;
return 0;
}
file << L"1234" << endl;
file << L"簡體中文abc" << endl;
file << L"¿Cómo estás?" << endl;
file << L"用戶輸入: " << wstr << endl;
cout << L"已成功寫入" << file.tellp() << L"字節" << endl;
file.close();
// 打開文件並從文件中讀取Unicode字符串
ifstream ifile("file.txt");
cout << endl << endl << endl << L"**********************文件中的內容*********************" << endl;
while (!ifile.eof())
{
ifile >> wstr;
cout << wstr << endl; // 顯示
}
ifile.close();
return 0;
}
【運行結果】