我用C编写了一个程序,将单词分解成音节,段和字母.它适用于ASCII字符,但我想制作适用于IPA和阿拉伯语的版本.
我在保存和执行各个角色的功能方面遇到了大量问题.我的编辑器和控制台都设置为UTF-8,如果我将它保存为char*,可以显示阿拉伯语文本,但是当我尝试打印wchars时,它们会显示随机的标点符号.
我的程序需要能够识别单个UTF-8字符才能工作.例如,对于单词'though',它将't'存储为音节[1]段[1]字母[1],h存储为音节[1]段[1]字母[2]等.我希望能够对非ASCII字符执行相同操作.
我基本上花了一整天研究unicode并尝试不同的方法,我不能让他们中的任何一个让我将阿拉伯字符存储为角色.
如果我完全误解了整个概念,或者它实际上是不可能在C中做我想做的事情,我不确定我是否只是在一路上做了一些愚蠢的语法错误,我应该给予起来尝试另一种语言......
我会大量地,大规模地,大量地欣赏你能提供的任何帮助!我对编程很陌生,但是unicode对我的工作起到了重要的作用,所以我想从头开始研究如何做.
我对unicode如何工作的理解(如果我出错的话):
我在编辑器中输入了一些文字.我的编辑器根据我设置的编码对其进行编码.因此,如果我将其设置为UFT-8,它将使用2字节序列0xd8 0xab编码阿拉伯字母ب,表示代码点U + 0628.
我编译它,将0xd8 0xab分解为二进制11011000 10101000.
我在命令提示符下运行它.命令提示符根据我设置的编码解释文本,因此如果我将其设置为UFT-8,则应将11011000 10101000解释为代码点U + 0628.Unicode算法还告诉它向我显示哪个版本的U + 0628,因为角色具有不同的形状,具体取决于它在单词中的位置.由于角色是独自一人,它将显示独立版本ب
我对在C中处理unicode的方法的理解:
选项A - 使用编码为UTF-8的单字节(http://www.nubaria.com/en/blog/?p=289)
使用编码为UTF-8的单字节.将我的所有数据类型保留为chars和char数组,并仅在我的代码中键入ASCII字符.如果我必须硬编码unicode字符,请将其作为数组输入格式:
const char kChineseSampleText[] = "\xe4\xb8\xad\xe6\x96\x87";
Run Code Online (Sandbox Code Playgroud)
我的问题是:
选项B - 使用wchar和朋友(http://icu-project.org/docs/papers/unicode_wchar_t.html)
使用字符交换为wchars,根据编译器,它包含2到4个字节.像strlen这样的字符串函数不起作用,因为它们期望字符是一个字节,但是我可以使用像wprintf这样的w函数.
我的问题是:
我根本无法打印阿拉伯字符!我可以让他们打印英文字母,但阿拉伯字符只是作为随机标点符号.
我已经尝试输入unicode代码点以及实际的阿拉伯字符,我已经尝试将它们打印到控制台和UTF-8编码的文本文件,我得到相同的结果,即使控制台和文本文件显示阿拉伯文本(如果作为char*输入).我最后把代码包括在内.
(值得一提的是,我知道很多人认为wchars是坏的,因为它们不是很便携,而且因为它们占用了ASCII字符的额外空间.但是在这个阶段,这些都不是真正的担心我 - 我只是编写程序在我自己的计算机上运行,程序只处理短字符串.)
选项C - 使用外部库
我已经阅读了各种评论,外部库是要走的路,所以我尝试过:
C编程库
http://www.cprogramming.com/tutorial/unicode.html建议用无符号长整数替换所有字符,并使用特殊函数迭代字符串等.该站点甚至提供了一个样本库供下载.
我的问题:
虽然我可以将字符设置为无符号长整数但我无法将其打印出来,因为printf和wprintf函数不起作用,并且网站上也没有提供库(我想这个库可能是为Linux设计的) ?某些数据类型无效,修改它们也不起作用)
ICU图书馆
我的问题:
我下载了ICU库,但是当我研究如何使用它时,我看到了诸如characterIterator之类的功能无法在C中使用(http://userguide.icu-project.org/strings).能够遍历字符对于我需要做的事情来说是完全基本的,所以我认为图书馆不适合我.
我的代码
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <locale.h>
#include <string.h>
int main ()
{
wchar_t unicode = L'\xd8ac';
wchar_t arabic = L'?';
wchar_t number = 0x062c;
FILE* f;
f = fopen("unitest.txt","w");
char* string = "??? ???????";
//printf - works
printf("printf - literal arabic character is \"?\"\n");
fprintf(f,"printf - literal arabic character is \"?\"\n");
printf("printf - char* string is \"%s\"\n",string);
fprintf(f,"printf - char* string is \"%s\"\n",string);
//wprintf - english - works
wprintf(L"wprintf - literal english char is \"%C\"\n\n", L't');
fwprintf(f,L"wprintf - literal english char is \"%C\"\n\n", L't');
//wprintf - arabic - doesnt work
wprintf(L"wprintf - unicode wchar_t is \"%C\"\n", unicode);
fwprintf(f,L"wprintf - unicode wchar_t is \"%C\"\n", unicode);
wprintf(L"wprintf - unicode number wchar_t is \"%C\"\n", number);
fwprintf(f,L"wprintf - unicode number wchar_t is \"%C\"\n", number);
wprintf(L"wprintf - arabic wchar_t is \"%C\"\n", arabic);
fwprintf(f,L"wprintf - arabic wchar_t is \"%C\"\n", arabic);
wprintf(L"wprintf - literal arabic character is \"%C\"\n",L'?');
fwprintf(f,L"wprintf - literal arabic character is \"%C\"\n",L'?');
wprintf(L"wprintf - literal arabic character in string is \"?\"\n\n");
fwprintf(f,L"wprintf - literal arabic character in string is \"?\"\n\n");
fclose(f);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出文件
printf - literal arabic character is "?"
printf - char* string is "??? ???????"
wprintf - literal english char is "t"
wprintf - unicode wchar_t is "?"
wprintf - unicode number wchar_t is ","
wprintf - arabic wchar_t is "("
wprintf - literal arabic character is "*"
wprintf - literal arabic character in string is ""
Run Code Online (Sandbox Code Playgroud)
我正在使用Windows 10,Notepad ++和MinGW.
编辑 这被标记为Light C Unicode库的副本,但我不认为它真的回答了我的问题.我已经下载了库并查看过,如果你愿意的话你可以叫我傻,但是我真的很喜欢编程而且我不懂库中的大部分代码,所以我很难工作我如何使用它实现我想要的.我搜索了图书馆的打印功能,却找不到...
我只是想保存一个UTF-8字符,然后再打印出来!我真的需要安装一个完整的库才能做到这一点吗?我真的很感激有人对我表示同情,并以宝贝的方式告诉我如何做到这一点......人们一直说我应该使用uint_32或者其他东西而不是wchar - 但是我如何打印这些数据类型呢?我可以用wprintf做到吗?!
C和UTF-8仍然相互了解.换句话说,IMO,C对UTF-8的支持很少.
是......可以存储和处理单个UTF-8字符......?
第一步是确定"??? ???????"是UTF-8编码的字符串.C明确支持这一点u8"??? ???????".
UTF-8 string是一系列的char.每个1到4 char代表一个Unicode字符.Unicode字符至少需要21位才能进行编码.然而,OP不需要将一部分string[]转换为Unicode字符,就像想要在UTF-8边界上分割该字符串一样多.通过查找UTF-8连续字节可以很容易地找到它.
以下形成1个Unicode字符,编码为UTF-8字符串,并带有终止空字符.然后打印那个短字符串.
char* string = u8"??? ???????";
for (char *s = string; *s; ) {
printf("<");
char u[5];
char *p = u;
*p++ = *s++;
if ((*s & 0xC0) == 0x80) *p++ = *s++;
if ((*s & 0xC0) == 0x80) *p++ = *s++;
if ((*s & 0xC0) == 0x80) *p++ = *s++;
*p = 0;
printf("%s", u);
printf(">\n");
}
Run Code Online (Sandbox Code Playgroud)
使用UTF8感知屏幕查看输出:
<?>
<?>
<?>
< >
<?>
<?>
<?>
<?>
<?>
<?>
<?>
Run Code Online (Sandbox Code Playgroud)