如何迭代unicode字符,并使用C中的printf在屏幕上打印它们?

如何迭代unicode字符,并使用C中的printf在屏幕上打印它们?,c,unicode,printf,C,Unicode,Printf,我想遍历所有(至少16位)unicode字符,并用C在屏幕上打印它们 我知道有一些相关的问题,但它们并不能解决C语言中的printf的问题,但这正是我想要实现的,如果可能的话。我想这应该是可能的,也许有一个我不知道的把戏 因为我想使用printf,所以我想到了这样的事情: for (int i = 0x0000; i <= 0xffff; i++) { //then somehow increment the string char str[] = "\u25A1\n";

我想遍历所有(至少16位)unicode字符,并用C在屏幕上打印它们

我知道有一些相关的问题,但它们并不能解决C语言中的printf的问题,但这正是我想要实现的,如果可能的话。我想这应该是可能的,也许有一个我不知道的把戏

因为我想使用printf,所以我想到了这样的事情:

for (int i = 0x0000; i <= 0xffff; i++) {

    //then somehow increment the string
    char str[] = "\u25A1\n";
    printf("%s", str);

    char str[] = "\u25A2\n";
    printf("%s", str);

    char str[] = "\u25A3\n";
    printf("%s", str);

    ...

}

for(int i=0x0000;i将16位Unicode码点转换为多字节字符序列的函数是;如果要处理32位码点,还有
C32R

#include <uchar.h>

mbstate_t ps;
char buf[MB_CUR_MAX];
size_t bytes = c16rtomb(buf, i, &ps);
if (bytes != (size_t) -1) {
  printf("%.*s\n", bytes, buf);
}
#包括
mbstate_t ps;
char buf[MB_CUR_MAX];
大小字节=c16rtomb(buf、i和ps);
如果(字节数!=(大小t)-1){
printf(“%s\n”,字节,buf);
}

如果
c16rtomb
不可用,您将需要使用特定于平台的设施。

我会选择类似的方式(使用原始UTF-8编码):

charunicode[3]={0x00,0x00,0x00};

对于(size\u t i=0;i如果定义了
\uu STDC\u ISO\u 10646\uuuu
宏,宽字符对应于Unicode码点。因此,假设可以表示您感兴趣的字符的区域设置,您可以通过
%lc
格式转换来使用
printf()
宽字符:

#include <stdio.h>
#include <locale.h>

#ifndef __STDC_ISO_10646__
#error "Oops, our wide chars are not Unicode codepoints, sorry!"
#endif
int main()
{
        int i;
        setlocale(LC_ALL, "");

        for (i = 0; i < 0xffff; i++) {
                printf("%x - %lc\n", i, i);
        }

        return 0;
}
#包括
#包括
#ifndef uu STDC_ISO_10646__
#错误“哦,对不起,我们的宽字符不是Unicode码点!”
#恩迪夫
int main()
{
int i;
setlocale(LC_ALL,“”);
对于(i=0;i<0xffff;i++){
printf(“%x-%lc\n”,i,i);
}
返回0;
}

在C99中,您可以使用宽字符到多字节字符转换函数,或者使用当前字符集将每个代码点转换为本地表示形式。(代码点位于当前字符集中,而不是Unicode)。请记住使用此函数以确保转换函数了解用户区域设置(最重要的是,使用的当前字符集)。转换函数使用
LC\u CTYPE
类别,但对于任何其他区域设置感知程序,您仍应使用
setlocale(LC\u ALL,”);

(并非所有系统都安装了
C.UTF-8
区域设置,因此我不建议尝试使用
setlocale(LC_all,“C.UTF-8”);
将区域设置覆盖到标准的C和UTF-8。它可以在某些系统上工作,但不能在所有系统上工作。例如,它在基于Fedora的Linux发行版中不起作用。)

因为您希望输出所有Unicode代码点,所以我建议使用不同的方法:使用通用字符集转换格式之一,即UTF-16(UCS-2在1996年被UTF-16取代)或UTF-32(也称为UCS-4).UTF-8是Web上最常用的一个,尤其是在您现在看到的这个网页上,而且非常易于使用

有关为什么选择UTF-8而不是“本机宽字符串”的更多信息,请参阅

如果您想要真正的可移植代码,可以使用此头文件utf8.h,将UTF-8转换为unicode代码点(
utf8\u to\u code()
),将unicode代码点转换为UTF-8(
code\u to\u utf8()
):

\ifndefutf8\u H
#定义UTF8\u H
#包括
#包括
#定义UTF8\u最大值6
静态大小utf8到代码(常量无符号字符*常量缓冲区,无符号整数*常量编码器)
{
如果(!缓冲区){
errno=EINVAL;
返回0;
}
如果(*缓冲区==0U){
errno=0;
返回0;
}
如果(*缓冲器<128U){
if(编码器)
*codeptr=缓冲区[0];
返回1;
}
如果(*缓冲器<192U){
errno=EILSEQ;
返回0;
}
如果(*缓冲器<224U){
如果(缓冲区[1]>=128U&&缓冲区[1]<192U)
返回((缓冲区[0]-192U)=128U&&缓冲区[1]<192U&&
缓冲区[2]>=128U和缓冲区[2]<192U)
返回((缓冲区[0]-224U)=128U和缓冲区[2]<192U&&
缓冲区[3]>=128U和缓冲区[3]<192U)
返回((缓冲区[0]-240U)=128U和缓冲区[3]<192U&&
缓冲区[4]>=128U和缓冲区[4]<192U)
返回((缓冲区[0]-248U)=128U和缓冲区[4]<192U&&
缓冲区[5]>=128U和缓冲区[5]<192U)
返回((缓冲区[0]-252U)>6U)&0x3FU);
缓冲区[2]=0x80U |(代码&0x3FU);
返回3;
}
如果(代码<2097152U){
缓冲区[0]=0xF0U |(代码>>18U);
缓冲区[1]=0x80U |(代码>>12U)和0x3FU);
缓冲区[2]=0x80U |(代码>>6U)和0x3FU);
缓冲区[3]=0x80U |(代码&0x3FU);
返回4;
}
如果(代码<67108864U){
缓冲区[0]=0xF8U |(代码>>24U);
缓冲区[1]=0x80U |(代码>>18U)和0x3FU);
缓冲区[2]=0x80U |(代码>>12U)和0x3FU);
缓冲区[3]=0x80U |(代码>>6U)和0x3FU);
缓冲区[4]=0x80U |(代码&0x3FU);
返回5;
}
如果(代码>30U);
缓冲区[1]=0x80U |(代码>>24U)和0x3FU);
缓冲区[2]=0x80U |(代码>>18U)和0x3FU);
缓冲区[3]=0x80U |(代码>>12U)和0x3FU);
缓冲区[4]=0x80U |(代码>>6U)和0x3FU);
缓冲区[5]=0x80U |(代码&0x3FU);
返回6;
}
errno=EINVAL;
返回0;
}
#endif/*UTF8\u H*/
它速度不快,但应该易于理解,并且在所有具有至少32位无符号整数的系统上支持所有可能的Unicode代码点(U+0000到U+10FFFF,包括在内)。在具有16位无符号整数的系统上,编译器可能会警告无法访问的代码,并且它只支持前65536个代码点(U+0000到U+FFFF)

使用上面的utf8.h,您可以轻松编写一个C程序,输出包含所需Unicode字符的HTML页面(不包括控制字符U+0000-U+001F和U+007F-U+00BF,以及无效代码点U+D800-U+DFFF)

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include "utf8.h"

int main(void)
{
    unsigned char  ch[UTF8_MAXLEN + 1];
    unsigned int   i;
    const char    *str;
    size_t         n, len;

    /* HTML5 DOCTYPE */
    printf("<!DOCTYPE html>\n");
    printf("<html>\n");

    /* Header part. */
    printf(" <head>\n");
    printf("  <title> Unicode character list </title>\n");
    printf("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
    printf("  <style type=\"text/css\">\n");
    /* with internal CSS stylesheet: */
    printf("   html {\n");
    printf("    font-family: \"DejaVu Mono\", \"Courier New\", \"Courier\", monospace;\n");
    printf("    font-weight: normal;\n");
    printf("    font-size: 100%%;\n");
    printf("    text-decoration: none;\n");
    printf("    background: #f7f7f7;\n");
    printf("    color: #000000;\n");
    printf("    padding: 0 0 0 0;\n");
    printf("    border: 0 none;\n");
    printf("    margin: 0 0 0 0\n");
    printf("   }\n");

    printf("   body {\n");
    printf("    background: #ffffff;\n");
    printf("    padding: 0.5em 1em 0.5em 1em;\n");
    printf("    border: 1px solid #cccccc;\n");
    printf("    margin: 0 auto auto auto;\n");
    printf("    width: 12em;\n");
    printf("    text-align: center;\n");
    printf("   }\n");

    printf("   p {\n");
    printf("    padding: 0 0 0 0;\n");
    printf("    border: 0 none;\n");
    printf("    margin: 0 0 0 0;\n");
    printf("    outline: 0 none;\n");
    printf("    text-align: center;\n");
    printf("   }\n");

    printf("   p.odd {\n");
    printf("    background: #efefef;\n");
    printf("   }\n");

    printf("   p.even {\n");
    printf("    background: #f7f7f7;\n");
    printf("   }\n");

    printf("   span.code {\n");
    printf("    width: 8em;\n");
    printf("    text-align: right;\n");
    printf("   }\n");

    printf("   span.char {\n");
    printf("    width: 4em;\n");
    printf("    text-align: left;\n");
    printf("   }\n");

    printf("  </style>\n");
    printf(" </head>\n");

    /* Body part. */
    printf(" <body>\n");

    n = 0;
    for (i = 0U; i <= 0xFFFFU; i++) {

        /* Skip Unicode control characters. */
        if ((i >= 0U && i <= 31U) ||
            (i >= 127U && i <= 159U))
            continue;

        /* Skip invalid Unicode code points. */
        if (i >= 0xD800U && i <= 0xDFFFU)
            continue;

        len = code_to_utf8(ch, i);
        if (len > 0) {
            ch[len] = '\0';

            /* HTML does not like " & < > */
            if (i == 32U)
                str = "&nbsp;";
            else
            if (i == 34U)
                str = "&#34;";
            else
            if (i == 38U)
                str = "&amp;";
            else
            if (i == 60U)
                str = "&lt;";
            else
            if (i == 62U)
                str = "&gt;";
            else
                str = (const char *)ch;

            if (n & 1) {
            printf("  <p class=\"odd\" title=\"%u in decimal, &amp;#%u; = %s\">", i, i, str);
                printf("<span class=\"code\">U+%04X</span>", i);
                printf(" <span class=\"char\">%s</span>", str);
                printf("</p>\n");
            } else {
                printf("  <p class=\"even\" title=\"%u in decimal, &amp;#%u; = %s\">", i, i, str);
                printf("<span class=\"code\">U+%04X</span>", i);
                printf(" <span class=\"char\">%s</span>", str);
                printf("</p>\n");
            }

            n++;
        }
    }

    printf(" </body>\n");
    printf("</html>\n");

    return EXIT_SUCCESS;
}
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include "utf8.h"

int main(void)
{
    unsigned char  ch[UTF8_MAXLEN + 1];
    unsigned int   i;
    size_t         len;

    for (i = 0U; i <= 0xFFFFU; i++) {

        /* Skip Unicode control characters. */
        if ((i >= 0U && i <= 31U) ||
            (i >= 127U && i <= 159U))
            continue;

        /* Skip invalid Unicode code points. */
        if (i >= 0xD800U && i <= 0xDFFFU)
            continue;

        len = code_to_utf8(ch, i);
        if (len > 0) {
            ch[len] = '\0';
            printf("U+%04X %s \n", i, ch);
        }
    }

    return EXIT_SUCCESS;
}
#
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include "utf8.h"

int main(void)
{
    unsigned char  ch[UTF8_MAXLEN + 1];
    unsigned int   i;
    const char    *str;
    size_t         n, len;

    /* HTML5 DOCTYPE */
    printf("<!DOCTYPE html>\n");
    printf("<html>\n");

    /* Header part. */
    printf(" <head>\n");
    printf("  <title> Unicode character list </title>\n");
    printf("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
    printf("  <style type=\"text/css\">\n");
    /* with internal CSS stylesheet: */
    printf("   html {\n");
    printf("    font-family: \"DejaVu Mono\", \"Courier New\", \"Courier\", monospace;\n");
    printf("    font-weight: normal;\n");
    printf("    font-size: 100%%;\n");
    printf("    text-decoration: none;\n");
    printf("    background: #f7f7f7;\n");
    printf("    color: #000000;\n");
    printf("    padding: 0 0 0 0;\n");
    printf("    border: 0 none;\n");
    printf("    margin: 0 0 0 0\n");
    printf("   }\n");

    printf("   body {\n");
    printf("    background: #ffffff;\n");
    printf("    padding: 0.5em 1em 0.5em 1em;\n");
    printf("    border: 1px solid #cccccc;\n");
    printf("    margin: 0 auto auto auto;\n");
    printf("    width: 12em;\n");
    printf("    text-align: center;\n");
    printf("   }\n");

    printf("   p {\n");
    printf("    padding: 0 0 0 0;\n");
    printf("    border: 0 none;\n");
    printf("    margin: 0 0 0 0;\n");
    printf("    outline: 0 none;\n");
    printf("    text-align: center;\n");
    printf("   }\n");

    printf("   p.odd {\n");
    printf("    background: #efefef;\n");
    printf("   }\n");

    printf("   p.even {\n");
    printf("    background: #f7f7f7;\n");
    printf("   }\n");

    printf("   span.code {\n");
    printf("    width: 8em;\n");
    printf("    text-align: right;\n");
    printf("   }\n");

    printf("   span.char {\n");
    printf("    width: 4em;\n");
    printf("    text-align: left;\n");
    printf("   }\n");

    printf("  </style>\n");
    printf(" </head>\n");

    /* Body part. */
    printf(" <body>\n");

    n = 0;
    for (i = 0U; i <= 0xFFFFU; i++) {

        /* Skip Unicode control characters. */
        if ((i >= 0U && i <= 31U) ||
            (i >= 127U && i <= 159U))
            continue;

        /* Skip invalid Unicode code points. */
        if (i >= 0xD800U && i <= 0xDFFFU)
            continue;

        len = code_to_utf8(ch, i);
        if (len > 0) {
            ch[len] = '\0';

            /* HTML does not like " & < > */
            if (i == 32U)
                str = "&nbsp;";
            else
            if (i == 34U)
                str = "&#34;";
            else
            if (i == 38U)
                str = "&amp;";
            else
            if (i == 60U)
                str = "&lt;";
            else
            if (i == 62U)
                str = "&gt;";
            else
                str = (const char *)ch;

            if (n & 1) {
            printf("  <p class=\"odd\" title=\"%u in decimal, &amp;#%u; = %s\">", i, i, str);
                printf("<span class=\"code\">U+%04X</span>", i);
                printf(" <span class=\"char\">%s</span>", str);
                printf("</p>\n");
            } else {
                printf("  <p class=\"even\" title=\"%u in decimal, &amp;#%u; = %s\">", i, i, str);
                printf("<span class=\"code\">U+%04X</span>", i);
                printf(" <span class=\"char\">%s</span>", str);
                printf("</p>\n");
            }

            n++;
        }
    }

    printf(" </body>\n");
    printf("</html>\n");

    return EXIT_SUCCESS;
}
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include "utf8.h"

int main(void)
{
    unsigned char  ch[UTF8_MAXLEN + 1];
    unsigned int   i;
    size_t         len;

    for (i = 0U; i <= 0xFFFFU; i++) {

        /* Skip Unicode control characters. */
        if ((i >= 0U && i <= 31U) ||
            (i >= 127U && i <= 159U))
            continue;

        /* Skip invalid Unicode code points. */
        if (i >= 0xD800U && i <= 0xDFFFU)
            continue;

        len = code_to_utf8(ch, i);
        if (len > 0) {
            ch[len] = '\0';
            printf("U+%04X %s \n", i, ch);
        }
    }

    return EXIT_SUCCESS;
}