百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

读书笔记之C Primer Plus 6

liebian365 2024-11-21 17:35 2 浏览 0 评论

为什么阅读《C Primer Plus》第六版

准备好好研究下redis源码,但是很久没用c语言写代码了,平时工作主要用java和js。
所以准备重新阅读学习下c语言经典书籍:C Primer Plus。
更好地阅读redis源码。


第13章 文件输入/输出

文件是当今计算机系统不可或缺的部分。文件用于存储程序、文档、数据、书信、表格、图形、照片、视频和许多其他种类的信息。

什么是文件

文件通常是在磁盘或固体硬盘上的一段已命名的存储区。
C提供两种文件模式:文本模式和二进制模式。

文本模式和二进制模式

所有文件的内容都以二进制形式存储。

  • 文本模式:如果文件最初使用二进制编码的字符(ASCII或Unicode)表示文本,该文件就是文本文件。
  • 二进制模式:如果文件中的二进制值代表机器语言代码或数值数据或图片或音乐编码,该文件就是二进制文件。
  • 在二进制模式中,程序可以访问文件的每个字节。
  • 在文本模式中,程序所见的内容和文件的实际内容不同。
  • 程序以文本模式读取文件时,把本地环境表示的行末尾或文件结尾映射为C模式。(比如\r转换成\n)
  • 除了以文本模式读写文本文件,还能以二进制模式读写文本文件

I/O的级别

  • 底层I/O(low-level I/O)使用操作系统提供的基本I/O服务
  • 标准高级I/O(standard high-level I/O)使用C库的标准包和stdio.h头文件定义
  • 标准高级I/Os比底层I/O容易跨平台移植。标准io使用缓冲区,底层io需要自己处理缓存。

标准文件

C程序会自动打开3个文件,它们被称为标准输入(standard input)、标准输出(standard output)和标准错误输出(standard error output)。
在默认情况下,标准输入是系统的普通输入设备,通常为键盘;标准输出和标准错误输出是系统的普通输出设备,通常为显示屏。

标准I/O

/* count.c -- 使用标准 I/O */
#include <stdio.h>
#include <stdlib.h>    // 提供 exit()的原型

int main(int argc, char *argv [])
{
     int ch;          // 读取文件时,存储每个字符的地方
     FILE *fp;        // “文件指针”
     unsigned long count = 0;
     if (argc != 2)
     {
          printf("Usage: %s filename\n", argv[0]);
          exit(EXIT_FAILURE);
     }
     if ((fp = fopen(argv[1], "r")) == NULL)
     {
          printf("Can't open %s\n", argv[1]);
          exit(EXIT_FAILURE);
     }
     while ((ch = getc(fp)) != EOF)
     {
          putc(ch, stdout);    // 与 putchar(ch); 相同
          count++;
     }
     fclose(fp);
     printf("File %s has %lu characters\n", argv[1], count);
     return 0;
}
  • return 0 和 exit 区别。

fopen函数

  • 函数声明在stdio.h中
  • 第一个参数:打开文件的包含该文件名的字符串地址。
  • 第二个参数:打开文件的模式,r=读模式,w=写模式
  • x模式:x模式的独占特性使得其他程序或线程无法访问正在被打开的文件
  • 成功打开文件后,fopen()将返回文件指针。
  • 文件指针不指向实际的文件,它指向一个包含文件信息的数据对象,其中有缓冲区信息。

getc和putc

  • ch = getchar(); 从标准输入中获取一个字符;
  • ch = getc(fp); 从fp指向的文件中获取一个字符;
  • putc(ch,fpout); 把字符ch放入FILE指针fpout指定的文件中;
  • 都定义在stdio.h中

文件结尾

返回一个特殊值EOF代表文件末尾

int ch;
FILE * fp;
fp = fopen("wacky.txt", "r");
while (( ch = getc(fp)) != EOF)
{
     putchar(ch);    //处理输入
}

fclose函数

  • 成功返回0
  • 失败返回EOF
  • 磁盘已满、移动磁盘移除或出现io错误,都会失败
if (fclose(fp) != 0)
     printf("Error in closing file %s\n", argv[1]);

指向标准文件的指针

stdio.h头文件把3个文件指针与3个标准文件相关联,C程序会自动打开这3个标准文件。

  • 标准输入 stdin
  • 标准输出 stdout
  • 标准错误 stderr

fprintf和fscanf

文件I/O函数fprintf()和fscanf()函数的工作方式与printf()和scanf()类似,区别在于前者需要用第1个参数指定待处理的文件。
都把FILE指针作为第一个参数,而不是最后一个参数。

fprintf(fp,"%s\n",words);
fscanf(fp,"%s",words);

fgets和fputs

  • fgets第一个参数表示存储输入位置的地址(char* 类型);
  • fgets第二个参数事一个整数,待输入字符串的大小;
  • fgets第三个参数是文件指针;
  • fgets(buf,STLEN,fp);
  • fgets读取输入直到第一个换行符的后面,或读到文件结尾,或者读取STLEN-1个字符;
  • 然后fgets在末尾添加一个空字符使之成为一个字符串;
  • fputs第一个参数是字符串的地址;
  • fputs第二个参数事文件指针;
  • 由于fgets保留了换行符,fputs就不会再添加换行符;

随机访问fseek和ftell

  • fseek第一个参数是FILE指针,fopen返回的文件指针
  • fseek第二个参数是编移量,必须是long类型的值,正(前移),负(后移)或0(保持不动)
  • fseek第三个参数事模式,该参数确定起始点,
  • stdio.h常量-> SEEK_SET文件开始处、SEEK_CUR当前闻之、SEEK_END文件末尾,旧的实现对应0L、1L、2L
  • ftell函数返回类型long,返回指向文件的当前位置距文件开始处的字节数;
  • last = ftell(fp);
fseek(fp,0L,SEEK_SET); //定位至文件开始处
fseek(fp,10L,SEEK_SET);//定位至文件中的第10个字符
fssek(fp,2L,SEEK_CUR);//从文件当前位置前移2个字节
fseek(fp,0L,SEEK_END);//定位至文件结尾
fseek(fp,-10L,SEEK_END);//从文件结尾处回退10个字节;

fgetpos和fsetpos

  • 不使用long类型,使用新类型:fpos_t文件定位类型
//调用该函数时,它把fpos_t类型的值放在pos指向的位置上,该值描述了文件中的当前位置距文件开头的字节数。如果成功,fgetpos()函数返回0;如果失败,返回非0。
int fgetpos(FILE * restrict stream,fpos_t * restrict pos);
//调用该函数时,使用pos指向位置上的fpos_t类型值来设置文件指针指向偏移该值后指定的位置。如果成功,fsetpos()函数返回0;如果失败,则返回非0。fpos_t类型的值应通过之前调用fgetpos()获得。
int fsetpos(FILE *stream,const fpos_t *pos);

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

int ungetc()函数把c指定的字符放回输入流中。

int fflush()函数

int fflush()函数

调用fflush()函数引起输出缓冲区中所有的未写入数据被发送到fp指定的输出文件。这个过程称为刷新缓冲区。

int setvbuf()函数

int setvbuf(FILE * restrict fp, char * restrict buf, int mode, size_t size);

setvbuf()函数创建了一个供标准I/O函数替换使用的缓冲区。在打开文件后且未对流进行其他操作之前,调用该函数。指针fp识别待处理的流,buf指向待使用的存储区。

fwrite和fread

  • fwrite把二进制数据写入文件
  • fwrite返回size_t类型
  • fread()函数接受的参数和fwrite()函数相同。
  • 在fread()函数中,ptr是待读取文件数据在内存中的地址,fp指定待读取的文件。
size_t fwrite(const void * restrict ptr, size_t size, size_t nmemb,FILE * restrict fp);
size_t fread(void * restrict ptr, size_t size, size_t nmemb,FILE * restrict fp);

读书总结

这章仔仔细细看了两遍,对c的标准I/O有了清晰的认识,不像java的IO这么多。java的io虽然灵活,但略显繁琐。

相关推荐

快递查询教程,批量查询物流,一键管理快递

作为商家,每天需要查询许许多多的快递单号,面对不同的快递公司,有没有简单一点的物流查询方法呢?小编的回答当然是有的,下面随小编一起来试试这个新技巧。需要哪些工具?安装一个快递批量查询高手快递单号怎么快...

一键自动查询所有快递的物流信息 支持圆通、韵达等多家快递

对于各位商家来说拥有一个好的快递软件,能够有效的提高自己的工作效率,在管理快递单号的时候都需要对单号进行表格整理,那怎么样能够快速的查询所有单号信息,并自动生成表格呢?1、其实方法很简单,我们不需要一...

快递查询单号查询,怎么查物流到哪了

输入单号怎么查快递到哪里去了呢?今天小编给大家分享一个新的技巧,它支持多家快递,一次能查询多个单号物流,还可对查询到的物流进行分析、筛选以及导出,下面一起来试试。需要哪些工具?安装一个快递批量查询高手...

3分钟查询物流,教你一键批量查询全部物流信息

很多朋友在问,如何在短时间内把单号的物流信息查询出来,查询完成后筛选已签收件、筛选未签收件,今天小编就分享一款物流查询神器,感兴趣的朋友接着往下看。第一步,运行【快递批量查询高手】在主界面中点击【添...

快递单号查询,一次性查询全部物流信息

现在各种快递的查询方式,各有各的好,各有各的劣,总的来说,还是有比较方便的。今天小编就给大家分享一个新的技巧,支持多家快递,一次能查询多个单号的物流,还能对查询到的物流进行分析、筛选以及导出,下面一起...

快递查询工具,批量查询多个快递快递单号的物流状态、签收时间

最近有朋友在问,怎么快速查询单号的物流信息呢?除了官网,还有没有更简单的方法呢?小编的回答当然是有的,下面一起来看看。需要哪些工具?安装一个快递批量查询高手多个京东的快递单号怎么快速查询?进入快递批量...

快递查询软件,自动识别查询快递单号查询方法

当你拥有多个快递单号的时候,该如何快速查询物流信息?比如单号没有快递公司时,又该如何自动识别再去查询呢?不知道如何操作的宝贝们,下面随小编一起来试试。需要哪些工具?安装一个快递批量查询高手快递单号若干...

教你怎样查询快递查询单号并保存物流信息

商家发货,快递揽收后,一般会直接手动复制到官网上一个个查询物流,那么久而久之,就会觉得查询变得特别繁琐,今天小编给大家分享一个新的技巧,下面一起来试试。教程之前,我们来预览一下用快递批量查询高手...

简单几步骤查询所有快递物流信息

在高峰期订单量大的时候,可能需要一双手当十双手去查询快递物流,但是由于逐一去查询,效率极低,追踪困难。那么今天小编给大家分享一个新的技巧,一次能查询多个快递单号的物流,下面一起来学习一下,希望能给大家...

物流单号查询,如何查询快递信息,按最后更新时间搜索需要的单号

最近有很多朋友在问,如何通过快递单号查询物流信息,并按最后更新时间搜索出需要的单号呢?下面随小编一起来试试吧。需要哪些工具?安装一个快递批量查询高手快递单号若干怎么快速查询?运行【快递批量查询高手】...

连续保存新单号功能解析,导入单号查询并自动识别批量查快递信息

快递查询已经成为我们日常生活中不可或缺的一部分。然而,面对海量的快递单号,如何高效、准确地查询每一个快递的物流信息,成为了许多人头疼的问题。幸运的是,随着科技的进步,一款名为“快递批量查询高手”的软件...

快递查询教程,快递单号查询,筛选更新量为1的单号

最近有很多朋友在问,怎么快速查询快递单号的物流,并筛选出更新量为1的单号呢?今天小编给大家分享一个新方法,一起来试试吧。需要哪些工具?安装一个快递批量查询高手多个快递单号怎么快速查询?运行【快递批量查...

掌握批量查询快递动态的技巧,一键查找无信息记录的两种方法解析

在快节奏的商业环境中,高效的物流查询是确保业务顺畅运行的关键。作为快递查询达人,我深知时间的宝贵,因此,今天我将向大家介绍一款强大的工具——快递批量查询高手软件。这款软件能够帮助你批量查询快递动态,一...

从复杂到简单的单号查询,一键清除单号中的符号并批量查快递信息

在繁忙的商务与日常生活中,快递查询已成为不可或缺的一环。然而,面对海量的单号,逐一查询不仅耗时费力,还容易出错。现在,有了快递批量查询高手软件,一切变得简单明了。只需一键,即可搞定单号查询,一键处理单...

物流单号查询,在哪里查询快递

如果在快递单号多的情况,你还在一个个复制粘贴到官网上手动查询,是一件非常麻烦的事情。于是乎今天小编给大家分享一个新的技巧,下面一起来试试。需要哪些工具?安装一个快递批量查询高手快递单号怎么快速查询?...

取消回复欢迎 发表评论: