簡體   English   中英

如何使用C++中的系統函數執行帶有多字節字符的命令

[英]How to execute a command with multi-byte characters using system function in C++

我正在嘗試執行以下操作:

string command = "executable.exe .\\テストプログラム\\filename.ext";
int retval = system(command.c_str());

在調試時,我發現多字節字符無法識別並且以隨機字符表示。

我還嘗試先將命令存儲在批處理文件中,然后再執行批處理文件。

filesystem::path batFile = filesystem::path(".\batFile.bat");
string command = "executable.exe .\\テストプログラム\\filename.ext";
writeBatCmd(batFile, command);
int retval = system(batFile.string().c_str());

我的發現是多字節字符正確存儲在 .bat 文件中,但在執行時,仍會出現與上述相同的情況。

在 cmd 中執行創建的 .bat 文件可以正確運行命令。

使用 CreateProcess 函數而不是系統函數不會改變行為。

我最初的猜測是需要將字符串轉換為 c_str 是導致該行為的原因,但將命令寫入 .bat 文件然后執行 .bat 反駁了它。

在此先感謝您的幫助!

編輯:

嘗試的解決方案:
解決方案1將locale 設置為utf8,然后直接調用程序。 執行程序的命令存儲在 wstring 對象中。 當多字節字符硬編碼在 wstring 對象中時,沒有問題。 例子:

wstring cmd = L"executable.exe .\\テストプログラム\\filename.ext";

執行這樣的操作時,從多字節字符開始到字符串末尾的字符將被截斷:

wstring cmd = L"executable.exe " + pathToFile + L"\\filename.ext";
// cmd value: "executable.exe .\"

解決方案2
我也嘗試過使用 u16string 對象,當使用它時,命令被正確存儲。 問題是我不能在它上面調用系統函數,因為它是 u16string,有沒有可以用於 u16string 的系統函數? 或者有沒有辦法將 u16string 轉換為 wstring 而不可能更改多字節字符?

u16string cmd = u"executable.exe .\\テストプログラム\\filename.ext";
// cmd value: executable.exe .\テストプログラム\filename.ext

解決方案3
我嘗試將語言環境設置為 utf8,然后將命令存儲在 .bat 文件中,然后執行 .bat 文件。 執行后,該命令會正確存儲在 .bat 文件中。 在調用 .bat 文件時,多字節字符不被識別/顯示為單字節字符。

setlocale(LC_ALL, "en_US.utf8");
filesystem::path batFile = filesystem::path(".\batFile.bat");
u16string cmd = u"executable.exe .\\テストプログラム\\filename.ext";
// cmd value: executable.exe .\テストプログラム\filename.ext
writeAsBat(batFile , cmd);
// batfile content: 
//executable.exe .\テストプログラム\filename.ext
//EXIT /B %ERRORLEVEL%
int retval = system(batFile.string().c_str());
/*
Output: 
in .bat file: executable.exe .\テストプログラム\filename.ext
on execution of .bat file: executable.exe .\チE¹トゅログラム\filename.ext
*/

Windows 在內部對所有系統功能使用 UTF-16。

如果您在調用 MBCS/ANSI 函數時,首先使用當前代碼頁將參數轉換為 UTF-16,然后進行解釋和執行。

如果您當前的代碼頁設置正確 - 並且 UTF-8 不是有效的代碼頁 - 那么這應該可以工作。 您可能需要代碼頁 932。

但是,您真的應該在 Windows 上為所有目的調用寬字符函數。

激活我的通靈調試能力,我猜你的 C++ 文件是 UTF-8 格式的。

自 2018 年 4 月更新,您現在可以將 UTF-8 設置為 C 中的當前字符集。 https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?view=msvc -160#utf-8-支持

開箱多一點

可能發生的情況是,當您編譯時,您的 C 字符串被轉換為字節序列,可能是 UTF-8 編碼。 然后將這些字節寫入批處理文件。 但是批處理文件不能用 UTF-8 編寫,它們可以用當前代碼頁編寫(無論如何,在您的情況下可能是日語代碼頁 932)。

解決您的問題

看起來您想編寫一個批處理文件,因為您在調用程序時遇到困難,並且已經找到了一個批處理文件作為解決方案。

如果是這種情況,您可能會更幸運地將 C 語言環境設置為 UTF-8,並直接調用程序,或者使用寬字符 API 來執行此操作。

https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?view=msvc-160#utf-8-support

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM