Как прочитать уже объявленную строку символов, которая является символом Unicode, в виде шестнадцатеричного двухзначного значения? - PullRequest
0 голосов
/ 05 февраля 2019

Учитывая две строки, я должен прочитать шестнадцатеричные 2-значные значения каждого из их значений Unicode.игнорируя символы ASCII.

char * str1 = "⍺";
char * str2 = "alpha is ⍺, beta is β and mu is µ";

Я попытался напечатать эти значения, используя: printf("<%02x>\n", str1);, но кажется, что значение неверно (также сделал это с (unsigned char), и это не сработало).

Вывод должен выглядеть примерно так

<e2>
<e8><a2><2e>

Вот мой полный код:

#include <stdio.h>
#include <string.h>

char *str1 = "⍺";
char *str2 = "alpha is ⍺, beta is β and mu is µ";
char *str3 = "β";
char *str4 = "µ";

int main(){
    printf("<%x>\n", (unsigned char) * str1);
    printf("<%x>", (unsigned char) * str1);
    printf("<%x>", (unsigned char) * str3);
    printf("<%x>\n", (unsigned char) * str4);
}

1 Ответ

0 голосов
/ 05 февраля 2019

Этот код проходит через байты строки и идентифицирует символы ASCII (Unicode U + 0000 .. U + 007F) и обычно не печатает их, а также для символов Unicode от U + 0080 и выше, выводит <, серию пар шестнадцатеричных цифр, представляющих символ, и, в конечном итоге, > в конце, с >< в середине, отделяющий отдельный символ Unicode в кодировке UTF8.Если вы передаете один или несколько аргументов, он также печатает символы «ASCII», но не в шестнадцатеричной кодировке.

#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>

static void dump_str(const char *s);

static bool print_ascii = false;

int main(int argc, char **argv)
{
    const char *strings[] =
    {
        "⍺",
        "alpha is ⍺, beta is β and mu is µ",
        "At -37ºC, the £ and the € fall apart",
        "嬀£Åºüÿ",
        "⍺βµ",
    };
    enum { NUM_STRINGS = sizeof(strings) / sizeof(strings[0]) };

    // Use argv - my compilation options don't allow unused parameters to a function
    if (argc > 1 && argv[argc] == NULL)
        print_ascii = true;

    for (int i = 0; i < NUM_STRINGS; i++)
        dump_str(strings[i]);
    return 0;
}

static void dump_str(const char *s)
{
    int c;
    bool printing_ascii = true;
    while ((c = (unsigned char)*s++) != '\0')
    {
        if (isascii(c))
        {
            if (!printing_ascii)
            {
                printing_ascii = true;
                putchar('>');
            }
            if (print_ascii)
                putchar(c);
        }
        else
        {
            if (printing_ascii)
            {
                printing_ascii = false;
                putchar('<');
            }
            else
            {
                if ((c & 0xC0) != 0x80)
                {
                    putchar('>');
                    putchar('<');
                }
            }
            printf("%2x", c);
        }
    }
    if (!printing_ascii)
        putchar('>');
    putchar('\n');
}

Я вызвал программу utf8-97;при запуске он дал мне:

$ ./utf8-97
<e28dba>
<e28dba><ceb2><c2b5>
<c2ba><c2a3><c2a0><e282ac>
<c3a5><c2ac><e282ac><c2a3><c385><c2ba><c3bc><c3bf>
<e28dba><ceb2><c2b5>
$ ./utf8-97 1
<e28dba>
alpha is <e28dba>, beta is <ceb2> and mu is <c2b5>
At -37<c2ba>C, the <c2a3><c2a0>and the <e282ac> fall apart
<c3a5><c2ac><e282ac><c2a3><c385><c2ba><c3bc><c3bf>
<e28dba><ceb2><c2b5>
$ 

Последовательность <c2a0> предназначена для неразрывного пробела, который я случайно вставил / оставил в коде после символа фунта £.Я не уверен, что вы получите это, если скопируете код из ответа.

...