当前位置:网站首页>C language file operation - detailed explanation of data file type, file judgment, and file buffer

C language file operation - detailed explanation of data file type, file judgment, and file buffer

2022-08-11 05:46:00 Yunyi 943

        之前,I explained the three steps of file manipulation,Explains various functions and usage of file reading and writing,今天,Let's talk with you about some remaining knowledge points of file operations.

        

一.数据文件类型

        Earlier I mentioned that files are divided by function type程序文件数据文件两大类,What we mainly explain in this section is the data file.The data files are also divided into two categories:文本文件、二进制文件.

1.Two types of definitions:

        文本文件:如果要求在外存上以ASCII码的形式存储,则需要在存储前转换.以ASCII字符的形式存储的文件is called a text file.

        二进制文件:数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件.

        在此同时,A new question arises:一个数据在内存中是怎么存储的呢?

        答案是:字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储.

       

        Let me give a representative example:整数10000The conclusion from the above question can be stored in memory using two methods:

方法1.10000are treated as characters:10000共有5个字符组成——1,0,0,0,0 ,通过ASCIIAfter the code value is stored,(一个字符占一个字节),ready to occupy5个字节的内存空间.

方法2.10000Treated as binary data:10000作为10进制整数,Convert it to two's complement and store it in memory,int类型数据会占用4个字节的内存空间.

        by the number given10000,我们可以看到10000Better to store in binary,因为比ASCIIThe form saves into the memory province1字节;If the number given is yes1,则选择ASCIIform in,1The binary form of is still 4stored in bytes.

        接下来,Take a look through the code10000The result stored in binary form:

#include <stdio.h>
int main()
{
 int a = 10000;
 FILE* pf = fopen("test.txt", "wb");
 fwrite(&a, 4, 1, pf);//二进制的形式写到文件中
 fclose(pf);
 pf = NULL;
 return 0;
}

调试结果如下:

        It can be known from the content stored in the file,10000The content stored in binary form is garbled,But it is known by binary encoding the file:10000的十六进制地址为10 27 00 00

 

整数10000的补码为:00000000 00000000 00100111 00010000

Simplified in hexadecimal:0x 00 00 27 10,因为VSThe compiler uses little-endian storage mode,So the displayed address is from low to high.

二.文件读取结束的判定

        牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束. 而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束.

        1.文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL( fgets ) 例如: fgetc 判断是否为 EOF . fgets 判断返回值是否为 NULL .

        2.二进制文件的读取结束判断,判断返回值是否小于实际要读的个数. 例如: fread判断返回值是否小于实际要读的个数.

一、文件结束检测函数feof函数调用格式: feof(文件指针);
功能:判断文件是否处于文件结束位置,如果Returns a non-zero value when the end of file has been reached, 其他情况返回0.

注意:feof ( )函数,读取文件的最后一个字符以后,C 语言的feof ( ) 函数依然返回 0,表明没有到达文件结尾;只有当fgetc ( ) 向后再读取一个字符(即越过最后一个字符),feof()才会返回一个非零值,表示到达文件结尾.



二、读写文件出错检测函数ferror函数调用格式: ferror(文件指针);
功能:检查文件在用各种输入输出函数进行读写时是否出错. 如ferror返回值为0表示未出错,否则表示有错.

1.文本文件的例子:

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    int c; // 注意:int,非char,要求处理EOF
    FILE* fp = fopen("test.txt", "r");
    if(!fp) {
        perror("File opening failed");
        return EXIT_FAILURE;
   }

    while ((c = fgetc(fp)) != EOF)    { 
       putchar(c);
   }


    if (ferror(fp))
        puts("I/O error when reading");
    else if (feof(fp))
        puts("End of file reached successfully");
    fclose(fp);
}

 

 

        This part is mainly when we read data from a file,If all data is read in a circular manner,Finally the loop stops,We need to judge the file pointer, In the end, it is the file pointer that reads everything normally,Point to the end encounteredEOFStop the cycle naturally;Or that the file pointer has an abnormal error during the reading process, which causes the loop to stop.

        这是一个有争议的话题,So the solution is to do a file pointerif..else的判断.


2.二进制文件的例子

#include <stdio.h>
enum { SIZE = 5 };
int main(void)
{
    double a[SIZE] = {1.,2.,3.,4.,5.};
    FILE *fp = fopen("test.bin", "wb"); // 必须用二进制模式
    fwrite(a, sizeof *a, SIZE, fp); // 写 double 的数组
    fclose(fp);

    double b[SIZE];
    fp = fopen("test.bin","rb");
    size_t ret_code = fread(b, sizeof *b, SIZE, fp); // 读 double 的数组

    if(ret_code == SIZE) {
        puts("Array read successfully, contents: ");
        for(int n = 0; n < SIZE; ++n) printf("%f ", b[n]);
        putchar('\n'); 
                         }

      else { // error handling
       if (feof(fp))
          printf("Error reading test.bin: unexpected end of file\n");
       else if (ferror(fp)) {
           perror("Error reading test.bin");
       }
   }

    fclose(fp);
}

 

        freadIf the return value is less than the actual number to be read,Indicates the end of binary file reading,Because there is none in the binaryEOF,只能用fread函数返回值进行判断,There are also two possible situations in which the reading ends: 


 三.文件缓冲区

        ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指:

The system automatically stores programs in memory 中每一个正在使用的文件开辟一块“文件缓冲区”.

      方向1:从内存向磁盘输出数据,会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上.

      方向2:如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓 冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等).

        注:缓冲区的大小根据C编译系统决定的.

        Design reasons for the buffer:

        由于CPU 与 I/O 设备间速度不匹配.为了缓和 CPU 与 I/O 设备之间速度不匹配矛盾.文件缓冲区是用以暂时存放读写期间的文件数据而在内存区预留的一定空间. 

 

原网站

版权声明
本文为[Yunyi 943]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/223/202208110512554370.html