[英]Printing to stderr on cmd fails to print first character of non-ASCII UTF-8 text
[英]UTF-8 decoder fails on non-ASCII characters
注意:如果您關注了我最近的問題,您會發現它們全都與我在C中的Unicode庫有關-作為我在C中的頭幾個重要項目之一,我遇到了很多問題,所以我對不起,如果我對一件事問太多問題。
我的庫的一部分將UTF-8編碼的char
指針解碼為原始的unsigned
代碼點。 但是,某些平面無法正確解碼。 讓我們看一下(相關的)代碼:
typedef struct string {
unsigned long length;
unsigned *data;
} string;
// really simple stuff
string *upush(string *s, unsigned c) {
if (!s->length) s->data = (unsigned *) malloc((s->length = 1) * sizeof(unsigned));
else s->data = (unsigned *) realloc(s->data, ++s->length * sizeof(unsigned));
s->data[s->length - 1] = c;
return s;
}
// UTF-8 conversions
string ctou(char *old) {
unsigned long i, byte = 0, cur = 0;
string new;
new.length = 0;
for (i = 0; old[i]; i++)
if (old[i] < 0x80) upush(&new, old[i]);
else if (old[i] < 0xc0)
if (!byte) {
byte = cur = 0;
continue;
} else {
cur |= (unsigned)(old[i] & 0x3f) << (6 * (--byte));
if (!byte) upush(&new, cur), cur = 0;
}
else if (old[i] < 0xc2) continue;
else if (old[i] < 0xe0) {
cur = (unsigned)(old[i] & 0x1f) << 6;
byte = 1;
}
else if (old[i] < 0xf0) {
cur = (unsigned)(old[i] & 0xf) << 12;
byte = 2;
}
else if (old[i] < 0xf5) {
cur = (unsigned)(old[i] & 0x7) << 18;
byte = 3;
}
else continue;
return new;
}
順便說一句,所有upush
所做的就是將代碼點壓入string
的末尾,根據需要重新分配內存。 ctou
進行解碼工作,並以字節為單位存儲序列中仍需要的byte
,以及以cur
為單位存儲進行中的代碼點。
該代碼對我來說似乎都是正確的。 讓我們嘗試解碼U+10ffff
,它是UTF-8中的f4 8f bf bd
。 這樣做:
long i;
string b = ctou("\xf4\x8f\xbf\xbd");
for (i = 0; i < b.length; i++)
printf("%z ", b.data[i]);
應該打印出來:
10ffff
但是它打印出來:
fffffff4 ffffff8f ffffffbf ffffffbd
它基本上是UTF-8的四個字節,前面加上ffffff
。
關於我的代碼有什么問題的任何指導?
允許對char類型進行簽名,並且先轉換為int然后再進行無符號轉換(當您直接轉換為unsigned時隱式發生)會顯示以下錯誤:
#include <stdio.h>
int main() {
char c = '\xF4';
int i = c;
unsigned n = i;
printf("%X\n", n);
n = c;
printf("%X\n", n);
return 0;
}
印刷品:
FFFFFFF4
FFFFFFF4
請改用unsigned char。
您可能已經忽略了char
是平台上的帶符號類型這一事實。 始終使用:
unsigned char
如果要讀取字節的實際值) signed char
char
代表抽象字符串,在這里您不需要關心任何值,除了0之外。 順便說一句,您的代碼效率極低。 而不是一遍又一遍地按字符調用realloc
,為什么不先分配sizeof(unsigned)*(strlen(old)+1)
,然后如果太大則減小其大小? 當然,這只是許多低效率中的一種。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.