用C语言中的俄语符号修改字符串

时间:2019-03-14 06:30:50

标签: c arrays string

我有代码:

#include <stdio.h>

int main() {
  char abc[] = "Hello";
  abc[0] = 'm';
  printf("%s\n", abc);
  return 0;
}

它会打印“ mello”,并且一切正常。

我还有另一个代码:

#include <stdio.h>

int main() {
  char abc[] = "Привет";
  abc[0] = 'm';
  printf("%s\n", abc);
  return 0;
}

它显示'm?ривет'。俄语符号怎么了?

1 个答案:

答案 0 :(得分:5)

俄语字母在系统上以UTF-8编码。他们为每个西里尔字母使用2个字节。您无法通过更改字符串中的各个char元素来更改字母,而必须从子字符串中构造新的字符串。

这是一个说明编码方式的程序:

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

int utf8_length(const char *s) {
    if (*s < 128)
        return 1;   // regular ASCII byte
    if (*s < 128+64)
        return -1;  // continuation byte, invalid code point
    if (*s < 128+64+32)
        return 2;   // code-point encoded on 2 bytes
    if (*s < 128+64+32+16)
        return 3;   // code-point encoded on 3 bytes
    if (*s < 128+64+32+16+8)
        return 4;   // code-point encoded on 4 bytes
    return -1;      // invalid code point
}

void test(const char *s) {
    int len = strlen(s);
    int i, nbytes;

    printf("Hex representation of %s:\n", s);
    for (i = 0; i <= len; i++) {
        printf("%02X ", (unsigned char)s[i]);
    }
    printf("\n");
    for (i = 0; i < len; i += nbytes) {
        nbytes = utf8_length(s + i);
        if (nbytes < 0) {
            printf("invalid encoding at %d\n", i);
        } else {
            printf("%*s%.*s ",
                   nbytes * 3 - 2 - (nbytes > 2), "",
                   nbytes, s + i);
        }
    }
    printf("\n\n");
}

int main() {
    char buf[128];
    char abc[] = "Привет";

    test("hello");  // English
    test(abc);      // Russian
    test("你好");   // Mandarin

    strcpy(buf, "m");
    strcat(buf, abc + utf8_length(abc));

    printf("modified string: %s\n", buf);
    test(buf);

    return 0;
}

输出:

Hex representation of hello:
68 65 6C 6C 6F 00
 h  e  l  l  o

Hex representation of Привет:
D0 9F D1 80 D0 B8 D0 B2 D0 B5 D1 82 00
    П     р     и     в     е     т

Hex representation of 你好:
E4 BD A0 E5 A5 BD 00
      你       好

modified string: mривет
Hex representation of mривет:
6D D1 80 D0 B8 D0 B2 D0 B5 D1 82 00
 m     р     и     в     е     т