環境
Windows 11 64bit
Visual Studio 2022
上一篇討論了如何用 C++ 讀取並顯示 windows 預設的 utf8 文字檔,這一篇來討論如何用 C++ 讀取並顯示 windows 的 ansi 和 unicode 文字檔
上一篇:C++ -讀取 txt 文字檔 中文亂碼問題
https://husking-studio.com/cpp-txt-file-01/
複習一下文字編碼
複習一下在上一篇提到過的用 C++ 在 windows 讀取 txt 文字檔會出現亂碼的原因
1. windows 預設的 txt 檔編碼方式是 utf8。
2. C++ 裡可以處理的字串編碼只有 ansi 和 unicode,沒有 utf8。
3. console 的命令提示字元視窗,預設顯示的編碼是 ansi。
1. 把 txt 檔存成 ansi
用記事本的另存新檔
選擇 ansi 就可以把 txt 檔的編碼改成 ansi 了
優點:C++ 裡使用的函式和 console 的編碼都可以不用更改
缺點:txt 檔只能儲存中文和英文
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream ifs;
char szAnsi[256] = "";
ifs.open("ansi_name.txt");
if (!ifs.is_open())
{
cout << "Failed to open file." << endl;
system("pause");
return 0;
}
ifs.read(szAnsi, sizeof(szAnsi));
ifs.close();
cout << szAnsi << endl;
system("pause");
return 0;
}
2. 把 txt 檔存成 unicode
建立一個 unicode_name.txt,內容是以下文字
哈利波特_해리 포터_Harry Potter_ハリー・ポッター |
用記事本的另存新檔選擇 UTF-16 LE
#include <iostream>
#include <fstream>
#include <windows.h>
#include <codecvt>
using namespace std;
void PrintfUnicode(const wchar_t* szFormat, ...) //在 console 印出 Unicode
{
const int MAX_PRINT_NUM = 1024;
wchar_t szPrint[MAX_PRINT_NUM] = L"";
va_list pArgs;
va_start(pArgs, szFormat);
vswprintf_s(szPrint, szFormat, pArgs);
va_end(pArgs);
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), szPrint, (DWORD)wcslen(szPrint), NULL, NULL);
}
int main()
{
wifstream ifs;
wchar_t szUnicode[256] = L"";
ifs.open("unicode_name.txt");
if (!ifs.is_open())
{
cout << "Failed to open file." << endl;
system("pause");
return 0;
}
ifs.imbue(locale(ifs.getloc(), new codecvt_utf16<wchar_t, 0x10ffff, consume_header>));
ifs.read(szUnicode, sizeof(szUnicode));
ifs.close();
PrintfUnicode(L"%s\n", szUnicode); //在 console 印出 Unicode
system("pause");
return 0;
}
順帶一提,用 Visual Studio 產生出來的 .h、.cpp、.c 等程式碼的文字檔,預設都是 ansi 的。你可以試試看如果在程式碼裡放個日文,會發生什麼事。
下一篇:C++ -讀取 txt 文字檔 命令列參數的問題
https://husking-studio.com/cpp-txt-file-03/
顏文字的 unicode
https://apps.timwhitlock.info/emoji/tables/unicode
https://www.unicode.org/emoji/charts/full-emoji-list.html