Кодировка UTF8 многобайтовых символов в C / Assembly - PullRequest
0 голосов
/ 27 мая 2020

У меня C программа, которая выглядит так:

#include <stdio.h>
#include <locale.h>
#include <wchar.h>
int main(void){
setlocale(LC_ALL,"en_US.utf8);
printf("%ls",(const wchar_t*)L"\u20AC\n");
}

Дизассемблированная версия такова:

.file   "ok.c"
    .text
    .section    .rodata
.LC0:
    .string "en_US.utf8"
    .align 4
.LC1:
    .string "\254 "
    .string ""
    .string "\n"
    .string ""
    .string ""
    .string ""
    .string ""
    .string ""
    .string ""
.LC2:
    .string "%ls"
    .text
    .globl  main
    .type   main, @function

Восьмеричный код UTF-8 для моего ввода, € (символ евро) - '\ 342 \ 202 \ 254'. Почему отображается только '\ 254' и почему остальные пробелы (исключая новую строку)? Без директивы L я тоже ничего не печатаю, а вывод asm выглядит примерно так: `.string '\ 343 \ 202 \ 254'?

1 Ответ

1 голос
/ 27 мая 2020

L"" и wchar_t не являются utf8 в вашей среде, это похоже на utf32. Итак, из-за порядка байтов я ожидаю, что ваши 4-байтовые wchar_t значения будут:

0xAC, 0x20, 0x00, 0x00  ; this is your \u20AC
0x0A, 0x00, 0x00, 0x00  ; this is the \n
0x00, 0x00, 0x00, 0x00  ; this is the end of string

Компилятор использовал тот факт, что 0x20 - это пробел в ascii и что .string автоматически генерирует нулевой байт, так:

.string "\254 "  ; 0xAC, 0x20, 0x00
.string ""       ; 0x00, so now you have your \u20AC
.string "\n"     ; 0x0A, 0x00
.string ""       ; 0x00
.string ""       ; 0x00, so now you have the \n
.string ""       ; 0x00
.string ""       ; 0x00
.string ""       ; 0x00
.string ""       ; 0x00, so now you have the terminating zero
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...