您的位置:首页 > 其它

字符编码及文件读取的基础知识

2014-07-18 22:58 218 查看
这是以前写的一点笔记,把它转过来。

1、二进制文件和文本文件

首先看二段代码:生成一个二进制文件和一个文本文件。打开一个二进制文件:test.dat,写入整数1234,其对应的十六进制为04 D2。



FILE *pfile;
    int ntest = 1234;
    if(NULL == (pfile=fopen("test.dat","wb")))
    {
        printf("can't write file:test.dat");
        return(1);
    }
    fwrite(&ntest,sizeof(int),1,pfile);
    fclose(pfile);




用ultraedit打开,可以看见:





然后:再次写一个文件:

FILE *pfile;
    int ntest = 1234;
    if(NULL == (pfile=fopen("test.bin","w")))
    {
        printf("can't write file:test.dat");
        return(1);
    }
//fwrite(&ntest,sizeof(int),1,pfile);
    fputs("1234", pfile);
    fclose(pfile);


打开后显示:







  世界上本没有文本文件,只说用的人多了才有了文本文件的概念。所有存储在计算机上的文件都是以二进制比特流的形式存在。有些比特流的特定多少位表示一个能可见的字符(比如说o1100101表示A),那么组成的文件就是通常所说的文本文件,除此之外的就是二进制文件了,二进制文件通常打开都是乱码,是因为你的工具(如记事本等)往往按照一个字节一个字节去读取二进制比特流,而有时候这个字节代表了一个不可见的字符,比如上面的D2。我们平时用的doc,bmp等文件都是二进制文件。

2、二进制文件和文本文件的打开方式



  文本方式和二进制方式仅仅是一种方式,不是说文本方式用来打开文本文件,二进制方式打开二进制文件。这两种方式的惟一区别就是:当利用文本方式打开文件时,遇到回车换行就转换成’\n’(windows需要转换,而linux系统不需要,这是因为windows与linux表示换行的标识符不一样,前者是\r\n,而后者是\n,与c语言规定的是一样的,在linux下面这两种方式没有区别。而且转化的工作由编译器完成,操作系统只负责处理数据流),而二进制方式没有这种转换。文本文件里的每个字节数据(当然也是用二进制存储在计算机上)一般都表示一个ascii(这里暂时只说ansi文本格式,对于unicode则不同了,后面会讲到),而二进制文件里的每个字节数据可能表示一个ascii也可能不是,当在ascii表中可以找到对应的字符时,你用文本编辑器打开时就能看见对应的字符,如果找不到就是乱码。



fread和fwrite往往用于读取和写入二进制文件,当然也可以读取和写入文本文件;反之,fgets和fputs往往用于文本文件的读取和写入,当然也可以读取和写入二进制文件。一切取决于你写入的数据格式和对读取的内容做什么样的解析。计算机只负责和二进制数据打交道,它不管你的二进制数据表示什么。





FILE *pfile;
    char buf[1024] = {'\0'};
    int nCount;
    if(NULL == (pfile=fopen("test.txt","r")))

    //if(NULL == (pfile=fopen("test.txt","rb")))
    {
        printf("can't write file:test.dat");
        return(1);
    }
    //fread(&ntest,sizeof(int),1,pfile);
    fgets(buf, 1024, pfile);
    //printf("%d\n",ntest);
    for (int na=0; na<1024 && buf[na]!=0; na++)
    {
        int ntemp = buf[na];
        ntemp &= 255;
        printf("%0.2x\n",ntemp);
    }
    fclose(pfile);




用文本方式打开结果:





用二进制方式打开:



3,Ansi/gbk/Unicode/utf-8





Ansi:最初是美国制定的一套标准,也就是ansi的ascii,用0-127表示一个字符。



GBK:中国为了支持汉字,用两个字节表示一个汉字。在判断这个字节大于127,说明是一个汉字编码的开始,然后读取下一个字节,组合在一起形成一个汉字。GBK里面小于127的字节表示的含义与ASCII一样。



Unicode:为了统一世界上各个国家的字符编码集,制定了一个统一的编码方案,概括了所有的语言字符,用2个字节表示。



Utf-8:实际上是unicode的一种实现形式。因为unicode只是规定了字符的编码内容,没有规定字符的存储方式。网络上的数据流往往以字节流的形式发送或者接收,utf-8规定了这些字节流的存储方式。



规定了这些字节流的存储方式。



UTF-8



0000 - 007F 0xxxxxxx



0080 - 07FF 110xxxxx 10xxxxxx



0800 – FFFF 1110xxxx 10xxxxxx 10xxxxxx



英文符号用1个字节表示,汉字一般用3个字节表示。实际上的对于英文,utf-8比ascii节省空间,而汉字则相反。



接下来出现了一个问题,当解析一个文本时,如何得知其编码方式,这里就是由各种文件的头标志决定的:



低位地址---->高位地址



EF BB BF UTF-8

FE FF UTF-16/UCS-2, big endian



FF FE UTF-16/UCS-2, little endian(小高高)

FF FE 00 00 UTF-32/UCS-4, little endian.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: