• C Primer Plus(十三)


    第十三章 文件输入/输出

    13.1 和文件进行通信

    程序和文件进行通信的一种方式就是文件重定向。

    13.1.1 文件是什么

    一个文件通常就是磁盘上的一段命名的存储区。
    C将文件看成是连续的字节序列,其中每一个字节都可以单独的读取。
    ANSI C提供了文件的两种视图:文本视图和二进制视图。

    13.1.2 文本视图和二进制视图

    在二进制视图中,文件中的每个字节都可以为程序所访问。在文本视图中,程序看到的内容和文件的内容有可能不同。
    例如使用文本视图读取文件时,将把行尾的本地环境表示法映射为C视图。与之类似,在输出的时候,也会将C视图中的行尾映射为本地环境表示法。

    13.1.3 I/O级别

    除了可以选择文件的视图,在大多数情况下,您可以在两个I/O级别中进行选择。
    低级I/O使用操作系统提供的基本I/O服务,标准高级I/O使用一个标准的C库函数包和stdio.h头文件中的定义。
    由于无法保证所有操作系统都可以用相同的低级I/O模型表示,所以ANSI C只支持标准I/O包。

    13.1.4 标准文件

    C程序自动为您打开三个文件。标准输入、标准输出、标准错误输出。

    13.2 标准I/O

    除了可移植性外,标准I/O包相对于低级I/O有两点优势。
    第一、标准I/O包中包含很多专用的函数,可以方便的处理不同的I/O问题。
    第二、对输入和输出进行了缓冲。这种缓冲大大提高了数据传输率。

    1. #include<stdio.h>
    2. #include<stdlib.h>
    3. int main(int argc,char *argv[])
    4. {
    5. int ch,
    6. FILE *fp;
    7. long count=0;
    8. if(argc!=2)
    9. exit(1);
    10. if(fp=fopen(argv[1],"r")==NULL)
    11. exit(1);
    12. while((ch=fgetc(fp))!=EOF)
    13. {
    14. putc(ch,stdout);
    15. count++;
    16. }
    17. fclose(fp);
    18. return 0;
    19. }

    13.2.1 检查命令行参数

    首先,检查argc的值,产看是否有命令行参数。字符串argv[0]是该程序的名称。
    exit()函数关闭所有打开的文件并终止程序。通常的约定是正常终止的程序传递值0,非正常终止的程序传递非0值。您也可以使用exit(EXIT_SUCCESS)和xit(EXIT_FAILURE)。
    按照ANSI C,在最初调用的main()中使用return和调用exit()的效果相同。  //注意是“最初调用”,如果main()在一个递归程序中,exit()仍然会终止程序。但return将控制权移交给递归的前一级,直到最初。

    13.2.2 fopen()函数

    程序用fopen()打开文件,它的第一个参数是要打开的文件名,或者说是包含该文件名的字符串的地址。第二个参数用于指定文件打开模式的一个字符串。
    如果使用任何一种“w”模式打开一个已有的文件,文件内容将被删除,以便程序以一个空文件开始操作。
    程序成功的打开一个文件后,fopen()函数返回一个文件指针,其它I/O函数用这个指针来指定该文件。
    如果不能打开文件,fopen()函数返回空指针。

    13.2.3 getc()和putc()函数

    这两个函数的工作方式和函数getchar()和putchar()非常相似,不同之处在于你需要告诉getc()和putc()函数它们要使用的文件。
    例如ch=getc(fp),putc(ch,fpout);
    putc(ch,stdout);第二个参数是标准输出相关的文件指针,所以其效果与putchar(ch)一样。

    13.2.4 文件结尾

    如果在尝试读入字符时发现已经达到文件结尾,getc()函数会返回一个特殊值EOF。
    所以可以加一个条件while((ch=fgetc(fp))!=NULL)来测试。

    13.2.5 fclose()函数

    fclose(fp)函数关闭由指针fp指定的文件,同时根据需要刷新缓冲区。如果成功关闭,返回值0,否则返回EOF。

    13.2.6 标准文件指针

    stdin和键盘 stdout和输出 stderr和显示器,这些指针都是FILE指针类型。

    13.3 文件I/O:fprintf()、fscanf()、fgets()和fputs()函数

    13.3.1 fprintf()和fscanf()函数

    1. #include<stdio.h>
    2. #include<stdlib.h>
    3. #define MAX 40
    4. int main(void)
    5. {
    6. FILE *fp;
    7. char words[MAX];
    8. if((fp=fopen("words","a+"))==NULL)
    9. {
    10. fprintf(stdout,"Can't open.\n");
    11. exit(1);
    12. }
    13. while(gets(words)!=NULL&&words[0]!='\0')
    14. fprintf(fp,"%s",words);
    15. rewind(fp);
    16. while(fscanf(fp,"%s",words)==1)
    17. puts(words);
    18. if(fclose(fp)!=0)
    19. fprintf(stderr,"erroe\n");
    20. return 0;
    21. }

    rewind()命令使程序回到文件开始处,这样最后的while循环就可以打印文件的内容。

    13.3.2 fgets()和fputs()函数

    fgets()函数接受三个参数,第一用于存储输入的地址。第二个参数为整数,表示输入字符串的最大长度。最后一个参数是文件指针,指向要读取的文件。
    fgets(buf,MAX,fp) 该函数读取它所遇到的第一个换行字符的后面,或者读取比字符串的最大长度少一个的字符,或者读取到文件结尾。然后fgets()函数向末尾添加一个空字符以构成一个字符串。
    所以字符串的最大长度代表字符的最大数目再加上一个空字符。如果在达到字符最大数目之前读完了一整行,它将在字符串的空字符之前添加一个换行符。
    fputs()函数接受两个参数,它们一次是一个字符串的地址和一个文件指针,将字符串写入指定文件。fputs(but,fp);

    13.3.3 gets()和fgets()函数

    fgets()函数可以防止存储溢出,所以对于严格的编程来说,它是一个更好的选择。

    13.4 随机存取:fseek()和ftell()函数

    fseek()函数允许你像对待数组那样对待一个文件,在fopen()打开的文件直接移动到任意字节处。它接受3个参数,返回一个int值,ftell()函数以一个long类型值返回一个文件的当前位置。
    在fseek()的三个参数中
    第一个参数是一个指向被搜索文件的FILE指针。应该已经使用fopen()打开了该文件。
    第二个参数称为偏移量,表示从起始点开始要移动的距离。这个参数必须是一个lon类型的值,可以为正(前移)、负(后移),也可以为零(保持不动)。
    第三个参数是模式,用来标识起始点。SEEK_SET:文件开始 SEEK_CUR:文件当前 SEEK_END:文件结尾
    例如:fseek(fp,0L,SEEK_SET);
    如果一切正常,fseek()返回值为0。有错误则返回-1。
    ftell()函数为long类型,它返回文件的当前位置。ftell()函数通过返回距文件开始处的字节数目来确定文件的位置,文件的第一个字节到文件开始处的距离是字节0,以此类推。
    last=ftell(fp);把从文件开始到文件结尾的字节数目赋给last。

    13.5 标准I/O内幕

    通常使用标准I/O的第一步就是用fopen()打开一个文件。fopen()函数不仅打开一个文件,而且建立了一个缓冲区,还创建了一个包含文件和缓冲区相关数据的数据结构。
    下一步就是调用stdio.h头文件中声明的某个输入函数,比如fscanf()等。会把一块数据从文件复制到缓冲区中。
    输出函数将数据写入缓冲区,缓冲区满的时候,就将数据复制到文件中。

    13.6 其它标准I/O函数

    13.6.1 int ungetc(int c ,FILE *fp)函数

    该函数将c指定的字符放回输入流中,如果向输入流中放人了一个字符,下一次调用标准输入函数就会读入那个字符。
    例如 ch=getchar();ungetc(ch,stdin);

    13.6.2 int fflush()函数

    函数原型为int fflush(FILE *fp);它能将缓冲区任何未写的数据发送到一个由fp指定的输出文件中去。这个过程称为刷新缓冲区。如果fp是一个空指针,将刷新掉所有的输出缓冲。

    13.6.3 int setvbuf()函数

    函数原型是 int setvbuf(FILE * restrict fp,char * restrict buf,int mode ,size_t size);
    setvbuf()函数建立了一个供标准I/O函数使用的替换缓冲区。打开文件后,在没有对流进行任何操作以前,可以调用这个函数。由fp来指定流,buf指向将使用的缓冲区。若buf为NULL,自动分配缓冲区。
    size变量为setvbuf()函数指定数组的大小。
    mode将从下列选项中选取:
    _IOFBF表示完全缓冲,_IOLBF表示行缓冲,_IONBF表示无缓冲。如果成功执行,函数返回零值,否则返回一个非零值。

    13.6.4 二进制I/O:fread()和fwrite()函数

    如果把数据存储在一个使用与程序具有相同表示方法的文件中,就称数据以二进制形式存储。对于标准I/0,fread()和fwrite()函数提供了这种二进制服务。
    实际上,所有的数据都是以二进制的方式进行存储的。如果文件中的全部数据都以字符编码的形式被解读,我们称该文件包含文本数据,如果部分或者全部以二进制形式解读,就称该文件包含二进制数据。
    char buffer[256];fwrite(buffer,256,1,fp);第三个参数表示数据块数目,这一调用将一块256字节大小的数据块从缓冲区写入到文件。
    double earning[10];fwrite(earnings,sizeof(double),10,fp);将数组中数据写入文件,数据分成10块,每块double大小。
    fread(earnings,sizeof(double),10,fp);恢复前一个例子中的数组,返回成功读入的项目数。

  • 相关阅读:
    idea 访问https://start.spring.io失败
    torch.nn.Dropout()
    torch.utils.tensorboard
    PyTorch 环境配置及安装
    np.reshape()
    torch.utils.data
    np.sum()
    Pytorch model.train()、model.eval()
    np.squeeze
    Python 临时文件、目录的生成
  • 原文地址:https://www.cnblogs.com/tuifeideyouran/p/3131218.html
Copyright © 2020-2023  润新知