Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C语言中,编码在什么时候起作用?那么字符串是如何正确打印的呢?_C_Character Encoding - Fatal编程技术网

在C语言中,编码在什么时候起作用?那么字符串是如何正确打印的呢?

在C语言中,编码在什么时候起作用?那么字符串是如何正确打印的呢?,c,character-encoding,C,Character Encoding,为了研究C如何处理UTF-8/Unicode字符,我做了一个小实验 这并不是说我现在正在尝试解决任何特定的问题,但我知道Java以一种对编码者透明的方式处理整个编码情况,我想知道C是如何处理它的字符的,它的级别要低得多 下面的测试似乎表明C完全不知道编码问题,因为只有显示设备知道如何在屏幕上显示字符时解释字符序列。后面的测试(当打印由包围的字符时)似乎很有说服力 #include <stdio.h> #include <string.h> int main() {

为了研究C如何处理UTF-8/Unicode字符,我做了一个小实验

这并不是说我现在正在尝试解决任何特定的问题,但我知道Java以一种对编码者透明的方式处理整个编码情况,我想知道C是如何处理它的字符的,它的级别要低得多

下面的测试似乎表明C完全不知道编码问题,因为只有显示设备知道如何在屏幕上显示字符时解释字符序列。后面的测试(当打印由
包围的字符时)
似乎很有说服力

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

int main() {
    char str[] = "João"; // ã does not belong to the standard 
                         // (or extended) ASCII characters

    printf("number of chars = %d\n", (int)strlen(str)); // 5

    int len = 0;
    while (str[len] != '\0')
        len++;
    printf("number of bytes = %d\n", len); // 5

    for (int i = 0; i < len; i++)
        printf("%c", str[i]);
    puts("");
    // "João"

    for (int i = 0; i < len; i++)
        printf("_%c_", str[i]);
    puts("");
    // _J__o__�__�__o_ -> wow!!!

    str[2] = 'X'; // let's change this special character
                  // and see what happens
    for (int i = 0; i < len; i++)
        printf("%c", str[i]);
    puts("");
    // JoX�o

    for (int i = 0; i < len; i++)
        printf("_%c_", str[i]);
    puts("");
    // _J__o__X__�__o_
} 
#包括
#包括
int main(){
char str[]=“João”;//ã不属于标准
//(或扩展)ASCII字符
printf(“字符数=%d\n”,(int)strlen(str));//5
int len=0;
而(str[len]!='\0')
len++;
printf(“字节数=%d\n”,len);//5
对于(int i=0;i

我知道ASCII/UTF-8是如何工作的,但我真正不确定的是字符在什么时候被解释为“复合”字符,因为C似乎只是将它们视为哑字节。这背后真正的科学是什么?

打印不是C语言的功能,而是显示上下文的功能,不管它是什么。对于终端,有UTF-8解码功能,可以将原始字符数据映射为使用特定字体显示在屏幕上的字符。在图形应用程序中也会出现类似的显示逻辑,但在比例字体宽度、连字、连字符和许多其他排版方面更为复杂

在内部,为了便于查找,通常首先将UTF-8解码为某种中间形式,如UTF-16或UTF-32。非常简单地说,字体中的每个字符都有一个Unicode标识符。实际上,这要复杂得多,因为存在字符变体的空间,多个字符可能由字体中的单个字符表示,如“fi”和“ff”。像“ç”这样的重音字符可以是字符的组合,这是Unicode允许的。这就是为什么会出现这样的情况:您常常可以将大量的Unicode“组合字符”堆叠到一个输出字符中

排版是一个复杂的世界,需要复杂的库才能正确渲染

您可以用C语言处理UTF-8数据,但只能使用特殊的库。C在标准库中附带的任何东西都不能理解它们,对于C来说,它只是一系列字节,并且它假定字节在长度上等同于字符。也就是说,strlen是以字节为单位的,而不是以字符为单位的

例如,C++更好地支持字节和字符之间的这种区别。其他语言甚至有更好的支持,像Swift这样的语言特别支持UTF-8,一般支持Unicode
打印与每个
str[i]
关联的字符-一次一个

当传递给
函数时,
char str[i]
的值将转换为
int
。然后,按照
%c“
和”的指示,将
int
值转换为
无符号字符
,并写入结果字符”

charstr[]=“João”不一定指定UTF8序列。这是一个实现细节。指定的方法是使用
char str[]=u8“João”自C11(或C99)起


printf()
未指定直接打印UTF8箍筋的方法。

是否将C文件保存为utf-8、MBCS或UCS-16?Linux还是Windows(哪个版本)?一个简单的答案是,Windows10倾向于完全支持UTF-8,UTF-8成为了各地的通用编码。那么,C中的UTF-8字符串实际上是一个哑字节数组,除非您尝试将其拆分为字符。嗨!我使用的是Ubuntu 16.04 LTS。CLion指出它是一个UTF-8文件(正如Linux中所预期的那样)。C编程语言于1978年发布。Unicode始于1991年。C语言不能很好地处理字符编码,这会让您感到惊讶吗?C语言是一种不幸的语言,其中字符必须是整型的。在所有普通语言中,字符都是一个字符长的字符串。不管它在内部是如何表示的,也不管它需要多少字节。所以你可以提取一个字符并打印出来,这样就行了。在C语言中,字符是一个字节,可以是UTF-8字符的任何部分。或者,使用更长的整数(16、32位…)。如果你对C++感兴趣,那么读一下关于CAR8YT..DeVuReDelysiIm,如果字符被发送到图形设备(终端,打印机),它就组装成可见的形式。如果字符被发送到文件,它们仍然是哑字节数组。C语言在这方面的作用很小。C++流知道更多的编码,但这种知识被普遍使用的UTF-8贬值。