C 知识点(5)
来源:互联网 发布:神反转的故事知乎 编辑:程序博客网 时间:2024/06/04 18:24
记录关于输入输出流和文件类型的相关知识点
文件的类型
大家都知道计算机的存储,物理上是二进制的,所以文本文件与二进制文件的区别并不是物理上的,而是逻辑上的。这两者只是在编码层次上有差异。简单来说,文本文件是基于字符编码的文件,常见的编码有 ASCII 编码,二进制文件是基于值编码
的文件。
* 文本文件:
以 ASCII 码格式存放,一个字节存放一个字符。 文本文件的每一个字节存放一个 ASCII 码,代表一个字符。这便于对字符的逐个处理,但占用存储空间
较多,而且要花费转换时间。
* 二进制文件:
以值(补码)编码格式存放。二进制文件是把数据以二进制数的格式存放在文件中的,其占用存储空间较少。 数据按其内存中的存储形式原样存放。
实例
接下来通过一个例子说明两者的区别: short int
型的变量在内存中占2个字节(8位)。
short int a = 10000;
数字10000
的二进制表示是 0010 0111 0001 0000
十六进制表示为0x2710
。
也就是说在计算机内存中变量a的值是以0x2710
表示的,也就是之前说的二进制文件。
接下来通过输出到文本中,验证之前的表述。
#include <stdio.h>int main(){ short a = 10000; FILE * fp = fopen("ascii.txt","w"); fprintf(fp,"%d",a); fclose(fp); FILE * fp2 = fopen("bin.txt","w"); fwrite(&a,2,1,fp2); fclose(fp2); return 0;}
分别以文本和二进制的形式输出到ascii.txt
、bin.txt
文件中。以十六进制格式查看。
// ascii.txt31 30 30 30 30 ;10000
在文本输出中,分别以ASCII码的形式表示了1 0 0 0 0
这5个数字。
// bin.txt10 27 ;
在二进制输出中,把内存中的储存形式直接输出到了txt文件中。
C语言中文件的输入输出
用到的函数和结构体
FILE 结构体
FILE 结构体是对缓冲区和文件读写状态的记录者,所有对文件的操作,都是通过
FILE 结构体完成的。
fopen 函数
以 Mode 的方式,打开一个 filename 命名的文件,返回一个指向该文件缓冲的 FILE 结构体指针。
Mode
fclose 函数
fclose()用来关闭先前 fopen()打开的文件. 此动作会让缓冲区内的数据写入文件中, 并释放系统所提供的文件资源.
单字符读写
fputc 函数
将 ch 字符,写入文件。
#include <stdio.h>int main(){ FILE* fp = fopen("ascii.txt","w"); if(fp == NULL) { printf("open error\n"); return -1; } for(char ch = 'A';ch<='Z';ch++) { fputc(ch,fp); } fclose(fp); return 0;}
fgetc 函数
从文件流中读取一个字符并返回。
#include <stdio.h>int main(){ FILE * fp = fopen("ascii.txt","r"); if(fp == NULL) { printf("open error\n"); return -1; } char ch; while((ch = fgetc(fp))!=EOF) printf("%2c",ch); fclose(fp); return 0;}
读取字符,重点是判断。
在C语言中,或更精确地说成C标准函数库中表示文件结束符(end of file)。在while循环中以EOF作为文件结束标志,这种以EOF作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的ASCII代码值的形式存放。我们知道,ASCII代码值的范围是0~127,不可能出现-1,因此可以用EOF作为文件结束标志。
feof 这个函数,是去读标志位判断文件是否结束的。即在读到文件结尾的时候 再去读一次,标志位才会置位,此时再来作判断文件处理结束状态,文件到结尾。如果用于打印,则会出现多打一次的的现象。所以普遍这样使用:
#include <stdio.h>int main(){ FILE * fp = fopen ("ascii.txt","w+"); if(fp == NULL) { printf("open erroe\n"); return -1; } for (char ch = 'a';ch<='z';ch++) { fputc(ch,fp); } rewind(fp); char ch; while ((ch = fgetc(fp))&& !feof(fp)) { printf("%3c",ch); } fclose (fp); return 0;}
即先读,判断标志位。因为读到末尾也可能会让标志位置位,进而跳出循环。
文本操作 (一次读一行)
fputs 函数
把 str 指向的字符串写入 fp 指向的文件中。
#include <stdio.h>int main(){ FILE * fp = fopen ("ascii2.txt","w"); if(fp == NULL) { printf("open erroe\n"); return -1; } fputs("abcdefghijk\n",fp); fputs("123456789\n",fp); char buf[] = "xyz"; fputs(buf,fp); fclose(fp); return 0;}
fputs 函数
从 fp 所指向的文件中,至多读 length-1 个字符,送入字符数组 str 中,如果在读入 length-1 个字符结束前遇\n 或 EOF,读入即结束,字符串读入后在最后加一个‘\0’字符。
fgets 函数返回有三个条件:
1. 读 n-1 个字符前遇到\n,读取结束。
2. 读 n-1 个字符前遇到 EOF,读取结束。
3. 最多读 n-1 个符,在每读一行后自动追加’\0’。
#include <stdio.h>int main(){ FILE * fp = fopen ("ascii2.txt","r"); if(fp == NULL) { printf("open erroe\n"); return -1; } char buf[1024]; while (fgets(buf,1024,fp) != NULL) { printf("%s",buf); } fclose(fp); return 0;}
二进制操作 (一次读写一块字符)
fwrite 函数
把 buffer 指向的数据写入 fp 指向的文件中
#include <stdio.h>#include <string.h>int main(){ FILE * fpw = fopen ("bin.txt","wb"); if(fpw == NULL) return -1; char * p = "china\nis\ngreat"; fwrite(p,1,strlen(p),fpw); fclose(fpw); return 0;}
输出结果
chinaisgreat
可以看出,不同于文本写入,二进制写入可吧特殊符号如\n
写入。
fread 函数
把 fp 指向的文件中的 数据读到 buffer 中
#include <stdio.h>#include <string.h>int main(){ FILE * fpr = fopen ("bin.txt","rb"); if(fpr == NULL) return -1; char buf[1024]; int n; n = fread(buf,1,1024,fpr); printf("n =%d\n",n); for(int i = 0;i<n;i++) { printf("%#x\t",buf[i]); } fclose(fpr); return 0;}
运行结果
0x63 0x68 0x69 0x6e 0x61 0xa 0x69 0x73 0xa 0x67 0x72 0x65 0x61 0x74
其中文本格式中的回车\n
,以0x0a
读回。此时的回车符号被当做一个普通的
数据。
fread/fwrite 函数的输入返回参数
函数声明如下
int fwrite (void *buffer , int num_bytes , int count , FILE *pf)int fread (void *buffer , int num_bytes , int count , FILE *pf)
num_bytes和count两个参数控制的是读写内容的大小。也就是读10个字节的内容, num_bytes=2
、count=5
与num_bytes=5
、count=2
两组参数的效果在读取内容上是相同的但是考虑到返回参数的含义,我们通常以读写内容的最小单位设定num_bytes的值。应为返回参数有如下定义:成功,返回读/写的字段数;出错或文件结束,返回 0。如果num_bytes的值与实际的读写单位大小不同,会造成返回值无意义或者无法通过返回值判断读写情况。
文件指针移动函数
- rewind : 将文件指针重新指向一个流的开头。
- ftell : 得到流式文件的当前读写位置,其返回值是当前读写位置偏离文件 头部的字节数。
- fseek : 偏移文件指针。
- C语言知识点-5
- C 知识点(5)
- c知识点
- C 知识点
- C/C++code知识点
- C/C++【知识点笔记】
- C基础知识点小记
- c#知识点 net
- C/C++知识点1
- c语言知识点
- C/C++面试知识点
- C语言知识点
- object-c 知识点
- [C++]指针知识点小结
- Objective-C知识点汇总
- Objective-C语言知识点
- C知识点累积篇
- C语言常见知识点
- Java高并发--等待通知和挂起继续执行
- 重写和重载知识总结
- C 知识点(4)
- 我对printf函数的一些理解
- 还是畅通工程(Kruskal)
- C 知识点(5)
- Territorial Dispute
- 非监督特征学习与深度学习(十二)---- 卷积神经网络
- vector drawable
- Python回顾
- MySQL LIKE 子句
- elipse快捷键
- 深入理解SELinux SEAndroid
- 推箱子