C++ -讀取 txt 文字檔 命令列參數的問題

環境
Windows 11 64bit
Visual Studio 2022

上上一篇:C++ -讀取 txt 文字檔 中文亂碼問題
https://husking-studio.com/cpp-txt-file-01/

上一篇:C++ -讀取 txt 文字檔
https://husking-studio.com/cpp-txt-file-02/

假設我的程式要處理這些不同語言的文字檔,那就必須使用命令列參數來處理

execute01.bat

@echo off
readtxtTest04.exe onepiece.txt
readtxtTest04.exe ワンピース.txt
readtxtTest04.exe 航海王简体中文.txt
readtxtTest04.exe 航海王繁體中文.txt
readtxtTest04.exe 원피스.txt
pause
#include <iostream>
#include <windows.h>
using namespace std;

void UTF8ToUnicode(wchar_t* szUni, const char* szUtf)	//把 UTF8 轉成 Unicode
{
    MultiByteToWideChar(CP_UTF8, 0, szUtf, -1, szUni, (int)strlen(szUtf) * 2);
}

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(int argc, char* argv[])
{
    char szArgv[32] = "";
    strcpy_s(szArgv, 32, argv[1]);

    cout << "szArgv =" << szArgv << endl;

    wchar_t szUnicode[64] = L"";
    UTF8ToUnicode(szUnicode, szArgv);
    PrintfUnicode(L"unicode = %s\n", szUnicode);

    system("pause");
    return 0;
}

我們先做簡單的測試吧

execute02.bat

@echo off
readtxtTest04.exe 中
pause

執行 execute02.bat 後,會得到下面的結果

嗯….都是亂碼

用捷徑的方式傳遞參數呢?

執行 捷徑 後,會得到下面的結果

用捷徑的方式傳遞參數是正常的,但是使用 batch 來傳遞參數卻會出現亂碼,為什麼呢?

原因就在於
傳遞參數這件事,是用 ansi 的編碼方式傳的,而 execute02.bat 這個 batch 檔本身是個 utf8 的文字檔,所以執行檔才會出現亂碼。

但即使送來的是 utf8 的字串,在 C++ 裡已經有使用轉碼函式了,為什麼還是亂碼?

咳..說實話,這我就真的不知道了,我已經將字碼都一個一個印出來檢查了,就是會有文字碼是錯的。batch 檔的 utf8 文字碼是正確的,但 C++ 那邊接收到的就會有一兩個字碼是錯的,如果有人知道原因的話,再請 mail 告訴我。

但現在還是要解決這問題

那把 batch 檔的編碼方式改成 ansi 不就好了。

修改 batch 檔的編碼方式確實能解決這個問題,但是把編碼方式改成 ansi 就不能儲存其他語言的文字了,所以 ワンピース.txt、원피스.txt 這些檔案該怎麼辦呢?你可別告訴我把檔名改成英文喔,你的程式是會給許多國家的使用者使用的,你不能去更改使用者的東西。

所以,「把 batch 檔的編碼方式改成 ansi」這方法不合適。

那到底該怎麼辦呢?

只能繞路了

把要處理的這些 txt 檔儲存在另一個 txt 檔裡,例如 filelist01.txt,再讓 C++ 讀取這個檔案應該就沒有問題了吧?

execute03.bat

@echo off
readtxtTest04.exe filelist01.txt
pause

這樣確實能解決這個問題,但總覺得不太方便。要自己在 filelist01.txt 裡面寫檔名就是覺得不方便,就不能自動幫我把放在資料夾裡的 txt 檔都自動處理了嗎?

batch 檔有一個指令,可以列出資料夾裡的所有檔案,並且儲存在一個 txt 檔裡

execute04.bat

@echo off
dir /b /on >filelist02.txt
pause

執行 execute04.bat 後會產生一個 filelist02.txt 檔

很好,ansi 的! (╯‵□′)╯︵┴────┴

那終於剩下最後一個問題了,要怎麼讓 batch 產生含有 unicode 文字的 txt 檔呢?

答案:把 cmd 的執行環境改成 utf8

execute05.bat

@echo off
chcp 65001
dir /b /on >filelist03.txt
pause

execute06.bat 列出檔名並執行程式

@echo off
chcp 65001
dir /b /on >filelist03.txt
readtxtTest04.exe filelist03.txt
pause

readtxtTest04 程式單純就是用命令列參數傳入 filelist03.txt,將裡面列出來的 txt 文字檔用「逗號」切 token,參考上一篇和上上一篇文章,這個程式就給你做練習囉。

這些日文、韓文檔可以這裡拿
https://www.dropbox.com/s/ik6cqp4hxahoer8/testfile.zip?dl=0

上上一篇:C++ -讀取 txt 文字檔 中文亂碼問題
https://husking-studio.com/cpp-txt-file-01/

上一篇:C++ -讀取 txt 文字檔
https://husking-studio.com/cpp-txt-file-02/

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *