環境
windows 11 64 bits
Visual Studio 2022
ansi 檔和 utf8 檔是完全分不出來的,因為它們沒有檔頭。嚴格來說,ansi 字串和 utf8 字串也是分不出來的。
用 ansi 編碼方式儲存的字串,英文使用 ascii code 編碼佔 1 個 byte,中文字使用 big5 編碼,佔 2 個 byte。
用 utf8 編碼方式儲存的字串,英文還是使用 ascii code 編碼,但是其他非英文字,包括中文、日文、韓文,則佔1~3 byte 不等。
參考 chatgpt 提供的方法,逐行讀取文件,將每一行轉換為 wchar_t,如果轉換過程中出現錯誤,比方說不是有效的 utf8 字符,則假設這是 big5 編碼的文件。
檢查是否是 utf8 文字檔的程式碼
#include <iostream>
#include <fstream>
#include <codecvt>
#include <string>
bool IsUtf8(const char *szFile)
{
std::ifstream file(szFile);
std::string line;
bool bIsUTF8 = true;
while (std::getline(file, line))
{
try
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wide_line = converter.from_bytes(line);
}
catch (const std::range_error&)
{
bIsUTF8 = false;
break;
}
}
return bIsUTF8;
}
完整程式碼
#include <iostream>
#include <fstream>
#include <codecvt>
#include <string>
bool IsUtf8(const char* szFile);
void CheckFile(const char* szFile);
int main()
{
CheckFile("ansi_test01.txt");
CheckFile("ansi_test02.txt");
CheckFile("ansi_test03.txt");
CheckFile("ansi_test04.txt");
CheckFile("ansi_test05.txt");
CheckFile("ansi_test06.txt");
CheckFile("utf8_test01.txt");
CheckFile("utf8_test02.txt");
CheckFile("utf8_test03.txt");
CheckFile("utf8_test04.txt");
CheckFile("utf8_test05.txt");
CheckFile("utf8_test06.txt");
system("pause");
return 0;
}
bool IsUtf8(const char *szFile)
{
std::ifstream file(szFile);
std::string line;
bool bIsUTF8 = true;
while (std::getline(file, line))
{
try
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wide_line = converter.from_bytes(line);
}
catch (const std::range_error&)
{
bIsUTF8 = false;
break;
}
}
return bIsUTF8;
}
void CheckFile(const char* szFile)
{
std::cout << szFile;
bool bIsUTF8 = IsUtf8(szFile);
if (bIsUTF8)
std::cout << " - utf8" << std::endl;
else
std::cout << " - big5" << std::endl;
std::cout << std::endl;
}
執行結果
參考資料
https://www.cns11643.gov.tw/pageView.jsp?ID=9
https://eric0806.blogspot.com/2014/07/detect-big5-or-utf8-encoding.html
https://blog.darkthread.net/blog/detect-big5-encoding
https://openhome.cc/Gossip/Encoding/TextFile.html