字符编码--第3章 字符的存储--ASCII(1967年)

原创
2015/09/05 16:23
阅读数 195

第3章 字符的存储

 

第1节 ASCII

ASCII(,American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语,而其扩展版本EASCII则可以部分支持其他西欧语言,并等同于国际标准ISO/IEC 646。由于万维网使得ASCII广为通用,直到2007年12月,逐渐被Unicode取代。

美国标准信息交换代码是由美国国家标准学会(American National Standard Institute , ANSI )制定的,标准的单字节字符编码方案,用于基于文本的数据。起始于50年代后期,在1967年定案。它最初是美国国家标准,供不同计算机在相互通信时用作共同遵守的西文字符编码标准,它已被国际标准化组织(International Organization for Standardization, ISO)定为国际标准,称为ISO 646标准。适用于所有拉丁文字字母。

ASCII第一次以规范标准的型态发表是在1967年,最后一次更新则是在1986年,至今为止共定义了128个字元;其中33个字元无法显示(一些终端提供了扩展,使得这些字符可显示为诸如笑脸、扑克牌花式等8-bit符号),且这33个字元多数都已是陈废的控制字元。控制字元的用途主要是用来操控已经处理过的文字。在33个字元之外的是95个可显示的字元,包含用键盘敲下空白键所产生的空白字元也算1个可显示字元(显示为空白)。

 

控制字符

Unicode表示法:当我们想在画面或纸张上表示这些控制字元时,就会显示成这个样子。过于老旧的系统或浏览器可能会看不到。使用微软任一中文输入法,输入`U2400即可看到␀,输入`U2401可看到␁,依此类推。

脱出字元表示法:通常用于终端机连线(例如Telnet通讯协定),以脱出字元^开头,再接一个符号,用来让这些控制字元得以在画面上显现。虽然看起来是两个字元,但在终端机上实际只有一个字元。在绝大部分的终端机系统中,包括Windows的命令提示字元(cmd.exe)、Linux和FreeBSD,都可用Ctrl代表脱出字元,输入想要的ASCII控制字元。例如想输入空字符,就要输入Ctrl+2,而非^@,后者会显示成两字元,前者只会显示成一字元。

 

二进制 十进制 十六进制 缩写 Unicode表示法 脱出字元表示法 名称/意义

0000 0000 0 00 NUL ␀ ^@ 空字符(Null)

0000 0001 1 01 SOH ␁ ^A 标题开始

0000 0010 2 02 STX ␂ ^B 本文开始

0000 0011 3 03 ETX ␃ ^C 本文结束

0000 0100 4 04 EOT ␄ ^D 传输结束

0000 0101 5 05 ENQ ␅ ^E 请求

0000 0110 6 06 ACK ␆ ^F 确认回应

0000 0111 7 07 BEL ␇ ^G 响铃

0000 1000 8 08 BS ␈ ^H 退格

0000 1001 9 09 HT ␉ ^I 水平定位符号

0000 1010 10 0A LF ␊ ^J 换行键

0000 1011 11 0B VT ␋ ^K 垂直定位符号

0000 1100 12 0C FF ␌ ^L 换页键

0000 1101 13 0D CR ␍ ^M Enter键

0000 1110 14 0E SO ␎ ^N 取消变换(Shift out)

0000 1111 15 0F SI ␏ ^O 启用变换(Shift in)

0001 0000 16 10 DLE ␐ ^P 跳出数据通讯

0001 0001 17 11 DC1 ␑ ^Q 设备控制一(XON 启用软体速度控制)

0001 0010 18 12 DC2 ␒ ^R 设备控制二

0001 0011 19 13 DC3 ␓ ^S 设备控制三(XOFF 停用软体速度控制)

0001 0100 20 14 DC4 ␔ ^T 设备控制四

0001 0101 21 15 NAK ␕ ^U 确认失败回应

0001 0110 22 16 SYN ␖ ^V 同步用暂停

0001 0111 23 17 ETB ␗ ^W 区块传输结束

0001 1000 24 18 CAN ␘ ^X 取消

0001 1001 25 19 EM ␙ ^Y 连线介质中断

0001 1010 26 1A SUB ␚ ^Z 替换

0001 1011 27 1B ESC ␛ ^[ 退出键

0001 1100 28 1C FS ␜ ^\ 文件分割符

0001 1101 29 1D GS ␝ ^] 群组分隔符

0001 1110 30 1E RS ␞ ^^ 记录分隔符

0001 1111 31 1F US ␟ ^_ 单元分隔符

0111 1111 127 7F DEL ␡ ^? 删除

 

可显示字符

 

缺点

ASCII的局限在于只能显示26个基本拉丁字母、阿拉伯数目字和英式标点符号,因此只能用于显示现代美国英语(而且在处理英语当中的外来词如naïve、café、élite等等时,所有重音符号都不得不去掉,即使这样做会违反拼写规则)。而EASCII虽然解决了部分西欧语言的显示问题,但对更多其他语言依然无能为力。因此现在的软件系统大多采用Unicode。

 

#include <stdio.h>

 

int main(int argc, char * argv) {

        short idx;

        for (idx = 0; idx <= 0x0FF; idx ++) {

                if (idx % 16 == 0) {

                        printf("\n");

                }

                printf("%c", (char) idx);

        }

 

    return 0;

}

 

 ☺☻♥♦♣

♫☼

►◄↕‼¶§▬↨↑↓→←∟↔▲▼

 !"#$%&'()*+,-./

0123456789:;<=>?

@ABCDEFGHIJKLMNO

PQRSTUVWXYZ[\]^_

`abcdefghijklmno

pqrstuvwxyz{|}~⌂

ÇüéâäàåçêëèïîìÄÅ

ÉæÆôöòûùÿÖÜ¢£¥₧ƒ

áíóúñѪº¿⌐¬½¼¡«»

░▒▓│┤╡╢╖╕╣║╗╝╜╛┐

└┴┬├─┼╞╟╚╔╩╦╠═╬╧

╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀

αßΓπΣσµτΦΘΩδ∞φε∩

≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ 

 

Chcp437

 

Chcp932

 

#include <stdio.h>

 

int to_upper(const char * in, int cnt, char * out) {

        char * p_in = ( char * )in;

        char * p_out = out;

        int i = 0;

        while (p_in != NULL) {

                if (i >= cnt) {

                        break;

                }

                if (*p_in >= 0x61 && *p_in <= 0x7A) {

                        *p_out = (*p_in) - 0x20;

                } else {

                        *p_out = *p_in;

                }

                // printf("@to_upper[%c]=>[%c].\n", *p_in, *p_out);

                p_in++;

                i++;

                p_out++;

        }

        return 0;

}

 

int main(int argc, char * argv) {

        short idx;

        char ch, ch1;

        for (idx = 0; idx <= 0x0FF; idx ++) {

                if (idx % 16 == 0) {

                        printf("\n");

                }

                ch1 = (char) idx;

                to_upper((const char *)&ch1, 1, &ch);

                printf("%c", ch);

        }

 

    return 0;

}

 

‑­

 !"#$%&'()*+,-./

0123456789:;<=>?

@ABCDEFGHIJKLMNO

PQRSTUVWXYZ[\]^_

`ABCDEFGHIJKLMNO

PQRSTUVWXYZ{|}~

€≠ヤ・㊧炎旧克・

髄駐舶沫・圀悃棔

。「」、・ヲァィゥェォャュョッ

ーアイウエオカキクケコサシスセソ

タチツテトナニヌネノハヒフヘホマ

ミムメモヤユヨラリルレロワン゙゚

珮粤蒟跚韜・・ⅰ

涇・

 

#include <stdio.h>

 

int to_upper(const char * in, int cnt, char * out) {

        char * p_in = ( char * )in;

        char * p_out = out;

        int i = 0;

        while (p_in != NULL) {

                if (i >= cnt) {

                        break;

                }

                if (*p_in >= 0x61 && *p_in <= 0x7A) {

                        *p_out = (*p_in) - 0x20;

                } else {

                        *p_out = *p_in;

                }

                // printf("@to_upper[%c]=>[%c].\n", *p_in, *p_out);

                p_in++;

                i++;

                p_out++;

        }

        return 0;

}

 

int to_lower(const char * in, int cnt, char * out) {

        char * p_in = (char *)in;

        char * p_out = out;

        int i = 0;

        while (p_in != NULL) {

                if (i >= cnt) {

                        break;

                }

                if (*p_in >= 0x41 && *p_in <= 0x5A) {

                        *p_out = (*p_in) + 0x20;

                }

                else {

                        *p_out = *p_in;

                }

                // printf("@to_upper[%c]=>[%c].\n", *p_in, *p_out);

                p_in++;

                i++;

                p_out++;

        }

        return 0;

}

 

int main(int argc, char * argv) {

        short idx;

        char ch, ch1;

        for (idx = 0; idx <= 0x0FF; idx ++) {

                if (idx % 16 == 0) {

                        printf("\n");

                }

                ch1 = (char) idx;

                // to_upper((const char *)&ch1, 1, &ch);

                to_lower((const char *)&ch1, 1, &ch);

                printf("%c", ch);

        }

 

    return 0;

}

 

‑­

 !"#$%&'()*+,-./

0123456789:;<=>?

@abcdefghijklmno

pqrstuvwxyz[\]^_

`abcdefghijklmno

pqrstuvwxyz{|}~

€≠ヤ・㊧炎旧克・

髄駐舶沫・圀悃棔

。「」、・ヲァィゥェォャュョッ

ーアイウエオカキクケコサシスセソ

タチツテトナニヌネノハヒフヘホマ

ミムメモヤユヨラリルレロワン゙゚

珮粤蒟跚韜・・ⅰ

涇・

内码

内码是指计算机汉字系统中使用的二进制字符编码,是沟通输入、输出与系统平台之间的交换码,通过内码可以达到通用和高效率传输文本的目的。比如MS Word中所存储和调用的就是内码而非图形文字。英文ASCII字符采用一个字节的内码表示,中文字符如国标字符集中,GB2312、GB12345、GB13000皆用双字节内码,GB18030(27,533汉字)双字节内码汉字为20,902个,其余6,631个汉字用四字节内码。

分类

字符编码:字符编码就是以二进制的数字来对应字符集的字符,目前用得最普遍的字符集是ANSI,对应ANSI字符集的二进制编码就称为ANSI码,DOS和Windows系统都使用了ANSI码,但在系统中使用的字符编码要经过二进制转换,称为系统内码。

汉字内码:ANSI码是单一字节(8位二进制数)的编码集,最多只能表示256个字符,不能表示众多的汉字字符,各个国家和地区在ANSI码的基础上又设计了各种不同的汉字编码集,以能够处理大数量的汉字字符。这些编码使用单字节来表示ANSI的英文字符(即兼容ANSI码),使用双字节来表示汉字字符。由于一个系统中只能有一种汉字内码,不能识别其它汉字内码的字符,造成了交流的不便。

GB码:GB码是1980年国家公布的简体汉字编码方案,在大陆、新加坡得到广泛的使用,也称国标码。国标码对6763个汉字集进行了编码,涵盖了大多数正在使用的汉字。

GBK码:GBK码是GB码的扩展字符编码,对多达2万多的简繁汉字进行了编码,简体版的Win95和Win98都是使用GBK作系统内码。

BIG5码:BIG5码是针对繁体汉字的汉字编码,在台湾、香港的电脑系统中得到普遍应用。

HZ码:HZ码是在Internet上广泛使用的一种汉字编码。

ISO-2022CJK码:ISO-2022是国际标准组织(ISO)为各种语言字符制定的编码标准。采用二个字节编码,其中汉语编码称ISO-2022 CN,日语、韩语的编码分别称JP、KR。一般将三者合称CJK码。CJK码主要在Internet网络中使用。

Unicode码:Unicode码也是一种国际标准编码,采用二个字节编码,与ANSI码不兼容。在网络、Windows系统和很多大型软件中得到应用。

 

内码转换

由于历史、地区原因,有时一种文字会出现多种编码方案,特别是汉字。由于不同于系统内码的字符不能在该系统中正常显示,必须要进行字符的内码转换,即将非系统内码的字符转换为系统可以识别的内码字符。南极星、四通利方、MagicWin98、两岸通、汉字通等都是这样的内码转换工具。

 

字符编码--第3章 字符的存储--EUC

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部