[英]MSVC is double-encoding UTF-8 strings, why?
所以,這里有一些簡單的代碼來重現我的問題:
#include <cstdio>
const char* badString = u8"aš𒀀";
const char* anotherBadString = u8"\xef\x96\xae\xef\x96\xb6\x61\xc5\xa1\xf0\x92\x80\x80";
const char* goodString = "\xef\x96\xae\xef\x96\xb6\x61\xc5\xa1\xf0\x92\x80\x80";
void printHex(const char* str)
{
for (; *str; ++str)
{
printf("%02X ", *str & 0xFF);
}
puts("");
}
int main(int argc, char *argv[])
{
printHex(badString);
printHex(anotherBadString);
printHex(goodString);
return 0;
}
我希望所有這些字符串都打印出相同的結果, EF 96 AE EF 96 B6 61 C5 A1 F0 92 80 80
。 但是,在 MSVC 2019 中,前兩個字符串打印出C3 AF C2 96 C2 AE C3 AF C2 96 C2 B6 61 C3 85 C2 A1 C3 B0 C2 92 C2 80 C2 80
。 這似乎是額外編碼為 UTF-8 的結果。
我在其他線程中讀到這個問題的解決方案是將/utf-8
標志添加到項目中,但我已經嘗試過,它沒有任何區別。 有沒有我在這里不理解的更基本的東西?
謝謝一堆!
第一個字符串的第一個字符是ï
(U+00EF,帶分音符的拉丁小寫字母 I),其 UTF-8 編碼為C3 AF
。
您顯然希望第一個字符串以 U+F5AE 開頭,但是您打開源文件的任何編輯器都與 MSVC 一致,即它不以該字符開頭。
源文件可能編碼為帶有BOM 的UTF-8 ,這就是/utf-8
標志不會改變任何內容的原因。 字符串在某個時候被破壞了,現在它被破壞的形式在文件中忠實地表示出來,MSVC 忠實地將它保存在編譯代碼中。
第二個字符串以\\xef
,MSVC 將其解釋為等效於\ï
,這又是ï
。 我在 C++20 草案標准中找不到任何關於\\x
在 UTF-8 字符串中應該意味着什么的明確聲明(盡管我看起來不是很努力)。 根據實驗,似乎除 MSVC 之外的大多數編譯器將\\x
后跟十六進制數字視為文字字節,即使這會使字符串無效 UTF-8。 我認為您不應該在u8
前綴字符串中使用\\x
,因為它不可移植(除了\\x00
到\\x7f
,可能)。 如果你想要 U+F5AE 然后寫\
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.