Chapter 13 文件输入、输出(File input/output)

要点总结

1. 与文件通信

  1. 程序与文件交互的形式是文件重定向。
  2. 文件通常是在磁盘或者固态硬盘上的一段已命名的存储区。C把文件看作是一系列连续的字节,每个字节都能被单独读取。C提供两种文件模式:文本模式和二进制模式。
  3. 所有文件的内容都以二进制形式存储。
    • 如果文本最初使用二进制编码的字符(ASCII/Unicode)表示文本,该文件就是文本文件,其中包含文本内容
    • 如果文件中的二进制值代表机器语言代码或者数据数值或者图片或音乐编码,该文件就是二进制文件,其中包含二进制内容
    • 二进制模式中,程序可以访问文件的每个字节。
    • 文本模式中,程序所见的内容和文件的实际内容不同。程序以文本模式读取文件时,把本地环境表示的行末尾或文件结尾映射为C模式。
    • 与文件模式相比,二进制模式更容易进行随机访问。

2. 标准I/O

  1. 文件访问的两个级别。底层I/O使用操作系统提供的基本I/O服务。标准I/O使用C库的标准包和stdio.h头文件定义,有3个好处:可移植性、拥有专门的函数简化处理不同的I/O问题、输入输出都是缓冲的。因为无法保证所有的操作系统使用相同的底层I/O模型,C标准只支持标准I/O包。
  2. C程序会自动打开3个文件:标准输入、标准输出和标准错误输出。默认情况下,标准输入是系统的普通输入设备,通常为键盘;标准输出和标准错误输出是系统的普通输出设备,通常为显示屏。
  3. exit()函数关闭所有打开的文件并结束程序。正常结束的程序传递0,异常结束的程序传递非0值。
  4. fopen()函数用来打开文件,第1个参数是待打开文件的名称,准确讲是一个包含改文件名的字符串地址。第2个参数是一个字符串,指定待打开文件的模式。成功打开后,该函数返回文件指针。文件指针的类型是指向FILE的指针,FILE是一个定义在stdio.h中的派生类型。文件指针并不指向实际的文件,它指向一个包含文件信息的数据对象,其中包含操作文件的I/O函数所用的缓冲区信息(缓冲区位置及被填充的程度以及操作哪一个文件)。
  5. 常见的模式
模式字符串含义
“r”以读模式打开文件
“w”以写模式打开文件,把现有文件的长度截为0(即从一个空白文件开始操作,原文件内容被删除);如果文件不存在,则创建一个新文件。
“a”以写模式打开文件,在现有文件末尾添加内容,如果文件不存在,则创建一个新文件
“r+”以更新模式打开文件,即可以读写文件
“w+”已更新模式打开文件,即可以读写,存在截为0;不存在,创建
“a+”以更新模式打开文件,即读写。在现有文件末尾添加内容
“rb”,…“a+b”与之前模式相同,但是是以二进制模式而不是文本模式打开文件
  1. getc()和putc() 与getchar()和putchar()函数类似。所不同的是,要告诉getc()和putc()函数使用哪一个文件。
    • getc()函数在读取一个字符时发现文件结尾,它将返回一个特殊值EOF。
    • ch = getchar() //从标准输入中获取一个字符。
    • ch = getc(fp) //从fp指定的文件中获取一个字符。
    • putc(ch, fpout) //把字符ch放入FILE指针fpout指定的文件中。putc(ch, stdout)与putchar(ch)的作用相同。
  2. fclose(fp)函数关闭fp指定的文件。成功关闭,则返回0,否则返回EOF。
  3. fprintf()与printf()类似,但是fprintf()的第1个参数必须时一个文件指针。
    8
    . fscanf()函数
    与scanf()类似,区别在于前者需要用第1个参数指定待处理的文件。
  4. **fgets()**与gets()函数类似,第1个参数表示存储输入位置的地址,第2个参数是一个整数,表示待输入字符串的大小,最后一个参数是文件指针,指定待读取的文件。fgets()函数读取输入直到第1个换行符的后面,或者读到文件结尾,或者读到待输入字符串减1个字符。然后,fgets()在末尾添加一个空字符使之成为一个字符串。字符串大小是其字符数加1。如果在读到字符上限之前已读完一整行,它会把表示行结尾的换行符放在空字符前面。fgets()函数在遇到EOF时将返回NULL值,可以利用这一机制检查是否达到文件末尾;如果未遇到EOF则之前返回传给它的地址。
  5. **fputs()**函数接受两个参数:第1个是字符串地址,第2个是文件指针。该函数根据传入地址找到的字符串写入指定的文件。和puts()函数不同,fputs()在打印字符串时不会在其末尾添加换行符。
  6. fseek()和ftell()函数让程序可以随机访问文件中的任意位置。fgetpos()和fsetpos()把类似的功能扩展到更大的文件。
  7. fseek()有3个参数,第1个参数是FILE指针,指向待查找的文件,第2个参数是偏移量。该参数表示从起始点开始要移动的距离。该参数是一个long类型,可以为正(前移)、负(后移)或0(保持不变)。第3个参数是模式,该参数确定起始点。该函数返回int类型的值。如果一切正常,返回0,否则返回-1。
    常见的起始点模式
模式偏移量的起始点
SEEK_SET文件开始处
SEEK_CUR当前位置
SEEK_END文件末尾

例如,fseek(fp, 0L, SEEK_SET); // 定位至文件开始处
fseek(fp, 10L, SEEK_SET) // 定位至文件中的第10个字节
fseek(fp, 0L, SEEK_END) // 定位至文件结尾
fseek(fp, -10L, SEEK_END) // 从文件结尾回退10个字节。

  1. **ftell()**函数的返回类型为Long,返回的是当前的位置。

  2. fread()和fwrite()函数直接使用的是二进制值。fread()函数将输入看作是二进制值并将其存储在指定存储位置。fwrite()将二进制数据直接放入输出流,而其他函数则把非字符数据转换成字符表示后才将其放入输出流。

  3. 程序都是单独打开和关闭每个文件,所以要打开几个文件,就要声明几个FIFL指针。

复习题

  1. 二进制文件和文本文件有何区别?二进制流和文本流有何区别?
  2. (1)分别用fprintf()和fwrite()存储8238201有何区别?
    (2
    )分别用putc()和fwrite()存储字符S有何区别?
  3. 下面语句的区别是什么?
    (1)printf(“Hello, %s\n”, name);
    (2)fprintf(stdout, “Hello, %s\n”, name);
    (3)fprintf(stderr, “Hello, %s\n”, name);
    解答
  • 二者的区别是这两种文件格式对 系统的依赖性不同。二进制流和文本流的区别是在读写流时程序执行的转换不同(二进制流不转换,而文本流可能要转换换行符和其他字符)。
  • (1)用fprintf()存储8238201时,将其视为7个字符,保存在7字节中。用fwrite()存储时,使用该数的二进制表示,将其视为一个4字节的整数。
  • (2)没有区别。两个函数都将其存储为一个单字节的二进制码。
  • 第1条语句是第2条语句的速记表示。第3条语句把消息写道标准错误中。通常标准错误被定向到与标准输出相同的位置。但是标准错误不受标准输出重定向的影响
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值