这么多函数,很多都没用过;顺序访问文件和随机访问文件的函数?
stdio.h就是一个文件。大型文件会被分开储存,或包含额外的数据,比如种类。
C语言把文件看做是一系列连续的字节而已,每个字节都能被单独读取。
文件的两种模式:文本模式和二进制模式。
所有文件都是以0,1存储的,但是如果这些字符有编码(如ASCII或Unicode),该文件就是文本。问:如何知道一个文本文件的编码方式?如果改变编码方式,文本文件进行二进制比较,仍相同吗?txt文件的”编码方式”存在什么地方?二进制文件比如图片或者音乐编码。(这里为什么用“编码”?)
GB2312是简体中文,Big5是繁体中文。
unix目录中有个统计文件大小的计数(为什么是目录中?)。
不同系统采用不同的格式处理文本文件:c和unix文件都是用\n表示换行,以前的OS X Macintosh文件用\r表示新的一行!MS-DOS文件用\r\n表示新行,用CTRL+Z表示文件结尾。
无论用notepad++还是ue都是看不见文件结尾是什么符号的??
二进制模式:程序可以访问文件的每个字节。
文本模式:程序所见的内容和文件实际的内容不同(怎么理解?)。例如,在上面的OS X Macintosh文本文件中换行为\r,C文本模式程序中就会把\r转换为\n;MS-DOS中会把\r\n转换为\n;反之亦然。
Windows中,在notepad++中输入回车,查看竟然是0d0a,也就是/r/n(注:最后的e4b8ad是“中”字,可以延伸研究一下)
底层I/O使用OS提供的基本I/O服务;
标准高级I/O使用C库的标准包和stdio.h头文件定义。
C程序自动打开3个文件(嗯?3个文件?)
- 标准输入(键盘):是getchar和scanf使用的文件;
- 标准输出和标准错误输出(都是显示器):是putchar、puts和printf使用的文件。
问:标准错误信息不能输出到文件中吗?
输入和输出都是缓冲的,一次转移一大块信息,通常是512字节。
注意:fopen在stdio.h中
查询:fopen打开文件的模式P437
想UNIX和Linux这样只有一种文件类型的系统,带b和不带b一样
UNIX和Linux只有一种文件类型??
冷知识:x模式及其不同点P437
FILE * fopen ( const char * filename, const char * mode );
返回的是指向FILE类型的指针。查询:FILE也是定义在stdio.h中
返回的fp指向FILE,而不是实际的文件。FILE中有缓冲区的信息,要知道缓冲区被填充到什么程度了(如何得知?)及操作哪个文件。I/O函数根据这些信息决定填充 或 清空缓冲区。查询:在第14章有这些信息。
13.2.3
getc、putc与getchar、putchar类似,区别是getc要告知文件,所以为什么不使用重载?
ch = getchar();
ch = getc(fp); // 看出区别了吧,这个是从文件获取一个字符。
putc(ch, fpout); // 把字符ch放入文件
putc(ch, stdout); // 和putchar(ch)相同! putc函数名短了,参数却要多一个
13.2.5
对于较正式的程序,应该检查是否成功关闭文件!如果关闭成功,返回0,否则返回EOF:
if (fclose(fp) != 0)
{
printf(…);
}
关闭失败的情况:磁盘已满、关闭U盘文件前U盘被移除、或出现I/O错误。
C自动打开了3个标准文件,对应的指针分别是stdin/stdout/stderr,问:如果用fclose把这三个文件关闭,还可以进行操作吗?P439
fprintf(); //可以把信息打印在显示器上吗?可以,例子中第一个参数用stderr。
同时打开文件进行读、写,同时打开文件的数量是有限的,一般是10~20个。
13.4
fprintf(), fscanf(), fgets(), fputs():
fprintf(), fscanf()和不带f版本的区别在于:第1个参数要指定待处理的文件(如果参数是stdin,“待处理的文件”就是显示器)。所以不要以为f开头就是文件,也可以是显示器!!
查询:rewind(fp); //倒回,回到文件开头,重写一遍?
a+模式,文件读写,为什么不是“wr”模式?同步查询R437表格,“r+”、”w+”、“a+”都有文件读写!!r+看不明白什么意思。w+:从头开始写;a+:从尾部开始写。
冷知识:还有x结尾的模式。看不懂。用到时再查查。
13.4.2
讲完fgetc和fputc,又来fgets和fputs
fgets(buf, STLEN, fp); // 变复杂了,3个参数,查询fgets和fputs,P443
13.5 随机访问fseek和ftell,先想一想,怎么随机访问?
有了fseek函数,便可把文件看做数组,在fopen打开的文件中直接移动到任意字节处。
问:代码 26 (CTRL-Z) 是 ASCII SUB 字符。为什么?SUB是什么意思?
定位到文件末尾:fseek(fp, 0, SEEK_END);
接着long last = ftell(fp); // 再利用fseek和getc回退找字符了!
fseek的第二个参数是偏移量,正(前移),负(后移),0(保持不动);第三个参数是模式,确定起始点。可以是文件开头(SEEK_SET,为什么不用start?),当前位置和文件结尾(SEEK_END),例如:
当前位置?ftell返回的就是当前位置!!比如从SEEK_END向前移10,再向后移2,第二次移动是否得用到当前位置了。
问:这些移动的目的,只是取值吗?比如移10后,可以修改移动之后的值吗?
文件的第一个字节,到文件开始处的距离是0。(但只适用于以二进制模式打开的文件)
fseek和ftell有什么问题?它们都把文件大小限制在long类型。因此,ANSI C又增加了两个处理交大文件的新定位函数:fgetpos和fsetpos, 使用新类型fpos_t(冷知识,P446)
问:fopen也和流的概念有关联?注意以后对比C++中的流。
问:这个结构包含哪些信息:1个当前位置指示器,错误和文件结尾指示器,1个指向缓冲区开始位置的指针,1个文件标识符(是什么)和1个计数(实际copy进缓冲区的字节数!!),这个结构在哪可以看到?
问:setvbuf函数有什么用?
13.7是其它标准I/O函数介绍
查询:P448,如果以后打算只用C++来读写文件,下面的是否需要理解?后面这些都没看,以后还是要看一下。
ungetc, fflush, setvbuf, fread, fwrite(二进制I/O), feof, ferror,
二进制I/O随机访问。