zoukankan      html  css  js  c++  java
  • 字符编码存储


    title: 字符编码存储
    date: 2019/02/26 23:31:59
    toc: true

    字符编码存储

    字符编码查看

    1. 可以使用notepad++ 更改编码方式,然后用hex查看
    2. Ue的话有快捷键ctrl+H

    mark

    中的gbk编码是D6D0,unicode的编码是4E2D

    utf8的解码很简单,我们以E4 B8 AD来解析.

    对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。

    1110 0100 , 1011 1000 , 1010 1101
    xxx 表示3个字节表示unicode
       x 这个表示长度结束符号
         开始编码
     
    

    mark

    字体

    一个文字,怎么显示?通过一个编码,找到具体的字模来达到具体的显示(点阵,公式等)

    所以一个字体应该包括了字符编码和字体显示点阵数据

    mark

    代码测试

    我们写下这样一句

    char * str_put="123中";
    

    这个里面到底是怎么存储的呢?实际上默认是按照代码文件的格式存储的.

    #include <stdio.h>
    
    int main(int argc, char ** argv)
    {
    	unsigned char * str_put="123中";
    	unsigned char * pt=str_put;
    	while(*pt)
    	{
    		printf("%02x ",*pt);
    		pt++;
    	}
    	printf("
    ");
    	return 0;
    	
    }
    

    测试保存不同的编码,我在保存u16编码的时候,无法编译过去

    
    [2019-02-26 21:57.29]  /mnt/d/test_encode
    [layty.layty-PC] ➤ gcc -o utf8 utf8.c
    ───────────────────────────────────────────────────────
    [2019-02-26 21:59.32]  /mnt/d/test_encode
    [layty.layty-PC] ➤ ./utf8.exe
    31 32 33 e4 b8 ad
    
    [layty.layty-PC] ➤ ./ansi.exe
    31 32 33 d6 d0
    
    

    为什么?

    其实是编码为gbk的时候,没有被gcc检测出错误,但不一定每次都能通过的.

    指定编码的理解

    man gcc 
    查找 charset
    // 输入文件编码 默认以utf-8编码
    -finput-charset=charset
    //生成的可执行程序的编码
    -fexec-charset=charset
    -fwide-exec-charset=charset
    
    
    -finput-charset=GBK
    -fexec-charset=UTF-8
    
    GBK
    UTF-8
    UTF-16BE 
    UTF-16LE 
    
    

    理解

    这里的指定文件编码应该这么理解

    1. 假设现在我们有一个char a="中";文件的编码是GBK

    2. gbk是兼容asc编码的,所以代码上一些其他的文字读取下来是没什么问题的,比如#include xxx

    3. 文件的具体的二进制实际上是已经定死的,也就是说你保存为GBK的时候,存储的就是d6 d0

    4. 这个时候指定输入文件为gbk,则解码d6 d0,我觉得这里内部会有一个转换为unicode编码的中间文件

    5. 然后如果我们不指定输出文件的格式,则默认就是utf8,也就是将d6 d0当作utf8,输出

      • 这个时候如果指定编码,我们再去转换这个中间文件的编码到指定的编码,默认还是utf8,所以输出还是d6 d0

    原始文件=按照-finput-charset=charset读取>按照-fwide-exec-charset=charset重新编码新的文件

    1. 所以如果我们指定输入文件格式为gbk的时候,他能正确解码d6 b0,转换成正确的unicode码,然后你就需要指定输出文件的编码才能打印出你想要的了

    比如存在如下代码

    char *s = "中国";
    printf("raw char[] is :");
    for(i=0;i<10;i++)
        printf("%x ",(*(s+i)&0xFF));
    
    输入 输出编码 打印
    utf8 utf8 d6 d0 b9 fa
    utf8 gbk 报错
    gbk utf8 e4 b8 ad e5 9b bd
    gbk gbk d6 d0 b9 fa

    如果文件是utf8编码的,则

    输入 输出编码(实际raw的存储的二进制) 打印
    utf8 utf8 e4 b8 ad e5 9b bd
    utf8 gbk d6 d0
    gbk utf8 报错
    gbk gbk 报错

    下面的代码以不同的编码保存,但是可以输出相同的结果

    
    char *s="中国";
    char buf[10];  
    
    printf("this file is encoding by gbk
    ");
    g2u(s, strlen(s), buf, sizeof(buf)); 
    
    printf("raw char[] is :");
    for(i=0;i<10;i++)
        printf("%x ",(*(s+i)&0xFF));
    printf("
    ");
    
    book@100ask:~/stu/code$ gcc -finput-charset=GBK  -fexec-charset=GBK  gbk_show.c
    book@100ask:~/stu/code$ ./a.out
    this file is encoding by gbk
    raw char[] is :d6 d0 b9 fa 0 74 68 69 73 20
    utf8 char[] is :e4 b8 ad e5 9b bd 0 0 0 0
    book@100ask:~/stu/code$ gcc   -fexec-charset=GBK  utf8_show.c
    book@100ask:~/stu/code$ ./a.out
    this file is encoding by gbk
    raw char[] is :d6 d0 b9 fa 0 74 68 69 73 20
    utf8 char[] is :e4 b8 ad e5 9b bd 0 0 0 0
        
        
        
    
    

    这样可以将gbk编码的文件编译成utf8编码的执行文件

    book@100ask:~/stu/code/yy$ gcc -finput-charset=GBK  -fexec-charset=UTF-8  ansi.c
    book@100ask:~/stu/code/yy$ ./a.out
    31 32 33 e4 b8 ad
    

    但是依然无法解决utf16编码的,后来查找原因有说该是<stdio.h>这个文件不是utf16编码导致的,尝试删除这个文件,去除printf后依然无法编译

    文件编码转换

    在搜索的时候发现可以使用iconv来转换文件,使用iconv -l能够列出字符集

    iconv -f UTF-16BE -t UTF-8 -o ff.c utf16-big.c  确实转换了格式拿到win7下查看
    

    然而我先转换为 UTF-16BE,再编译这个文件依然过不去

    iconv -t  UTF-16BE -f UTF-8 -o ff.c utf8.c
    book@100ask:~/stu/code/yy$ gcc -finput-charset=UTF-16BE -fexec-charset=UTF-8 -o -o aa ff.c
    
    

    所以我觉得可以先将文件转换为utf-8,再来编译

  • 相关阅读:
    『转载』优秀ASP.NET程序员的修炼之路
    [转]给年轻工程师的十大忠告
    [转]谈谈技术原则,技术学习方法,代码阅读及其它
    【转贴】你必须知道的20个故事
    谈谈建站心得(转载)[精华]
    HTTP和SOAP完全就是两个不同的协议
    数据集的理解IDataset
    学习在 ArcEngine 中使用 Geoprocessing
    程序执行过程
    How to Run a Geoprocessing Tool
  • 原文地址:https://www.cnblogs.com/zongzi10010/p/10492451.html
Copyright © 2011-2022 走看看