终止(可能)多字节字符串?
我正在研究C代码,并努力寻找一种方法来终止特定数量的字符后的字符串。例如,我需要在3个字符后终止字符串data
。如果它是一个纯ASCII字符串,我可以这样做终止(可能)多字节字符串?
data[3] = 0;
但在我的情况下,任何字符可以是多字节像E或A。给定数量的个字符后终止此字符串的最佳方法是什么?
UPDATE:
基本上是:
char s_mon[7];
setlocale(LC_ALL, "");
strftime(s_mon, 7, "%b", tick_time);
当前区域设置为法语。月份被存储为“févr。”。需要它是“fév”,但这需要具有普遍性,所以像“mars”这样的条目也可以缩减为3个字符。
结束重用此utf_str_to_upper函数。该函数正确处理多字节值。它也将字符串转换为大写(我也需要),但如果需要,可以剥离该功能。
我做的唯一修改是传递第二个参数limit
,这是字符的限制,在这个字符处我需要剪切字符串。该函数然后将终止符插入正确的字节位置并返回字节位置。下面是完整的代码:
uint8_t utf8_str_to_upper(char* s, uint8_t limit) {
uint8_t char_no = 0;
uint8_t* p;
for (p = (uint8_t*)s; *p; ++p) {
// (<128) ascii character
// U+00000000 – U+0000007F: 0xxxxxxx
if (*p < 0b10000000) {
if (*p >= 0x61 && *p <= 0x7A) {
*p = *p - 0x20; // a~z -> A~Z
}
// (<192) unexpected continuation byte
} else if (*p < 0b11000000) {
// (<224) 2 byte sequence
// U+00000080 – U+000007FF: 110xxxxx 10xxxxxx
} else if (*p < 0b11100000) {
uint16_t code = ((uint16_t)(p[0] & 0b00011111) << 6) | (p[1] & 0b00111111);
if (
(code >= 0x00E0 && code <= 0x00F6) || // à~ö -> À~Ö
(code >= 0x00F8 && code <= 0x00FE) // ø~þ -> Ø~Þ
) {
code -= 0x0020;
p[0] = 0b11000000 | ((code >> 6) & 0b00011111);
p[1] = 0b10000000 | (code & 0b00111111);
}
++p;
// (<240) 3 byte sequence
// U+00000800 – U+0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
} else if (*p < 0b11110000) {
p += 2;
// (<248) 4 byte sequence
// U+00010000 – U+001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
} else if (*p < 0b11111000) {
p += 3;
// (<252) 5 byte sequence
// U+00200000 – U+03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
} else if (*p < 0b11111100) {
p += 4;
// (<254) 6 byte sequence
// U+04000000 – U+7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
} else if (*p < 0b11111110) {
p += 5;
}
if (limit) {
char_no++;
if (char_no == limit) {
*(p + 1) = 0;
return p-(uint8_t*)s + 1;
break;
}
}
}
return p-(uint8_t*)s + 1;
}
请注意,在Unicode中,é可以表示为预先组合的字符,也可以表示为基本字符+变音符号,因此您首先需要将输入规范化为适当的形式,例如:将NFC作为预先组合字符。 – ninjalj
@ninjalj实际上在这种情况下(卵石开发)我必须决定组成字符到多字节才能正确显示。我背负的这个功能是处理这个https://github.com/jrmobley/pebble-utf8的软件包的一部分 –
什么是'data' –
根据编码声明(你应该知道你正在使用的编码),对于使用多字节序列精确的规则。你从左到右分析字符串,考虑这些规则,直到你越过第N个字符。然后你可以放一个零(对于UTF-8,例如单个0就可以)。 – linuxfan
''','''''''''''''''''''''''''''''''''''请勿需要“多字节”。使用[8859-1](https://en.wikipedia.org/wiki/ISO/IEC_8859-1),它们只是代码200和192.你使用的字符集是什么?代码是如何读取文本的? – chux