赞
踩
磁盘上的文件是文件。
在程序设计中,我们一般读的文件有两种:程序文件 和 数据文件
程序文件包括源程序文件(后缀为.c)、目标文件(win下后缀为 .obj)、可执行文件(win下环境后缀为.exe)
数据文件:文件的内容不一定是程序,而是运行时读写的程序,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
一个文件要有一个唯一的文件标识,以便于用户识别与引用。
文件名包含3部分:文件路径+文件名主干+文件后缀
c:\code\test.txt
文本文件:肉眼看得懂的东西
二进制文件:数据在内存中中以二进制形式存储,如果不加转换的输出到外存,就是二进制文件。
如果要求在外存上以ASCII码的形式存储,则需要在存储前转换,以ASCII字符(对应ASCII的值)的形式存储的文件就是文本文件。
文件类型指针(文件指针)
每个被使用的文件都在内存中开辟一个相应的文件信息区,用来存放文件的相关信息(如文件名字,文件状态,文件当前的位置)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名为FILE
.
vs2019编译环境中提供的 stdio.h
头文件中有以下的文件类型声明。
#ifndef _FILE_DEFINED
#define _FILE_DEFINED
typedef struct _iobuf
{
void* _Placeholder;
} FILE;
#endif
不同C编译器的FILE类型包含内容大同小异。
每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。
一般都是通过FILE的指针来维护这个FILE结构的变量。
FILE *pf;
定义pf是一个指向FILE类型数据的指针变量,可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量可以找到与他关联的相关文件。
总结:每个被使用的文件都在内存中开辟一个相应的文件信息区,用来存放文件的相关信息,这个相关信息是个结构体,使用typedef类型重新定义,也就是FILE
。
在打开文件的同时,会返回一个FILE*
的指针变量指向该文件,也相当于建立了指针和文件的关系。
ANSIC规定使用fopen来打开文件,fclose来关闭文件。
相对路径写法(当前代码所在路径下)
… 表示上一级路径
. 表示当前路径
FILE* p = fopen("../test.txt","r"); //打开当前路径低下 的test文件
绝对路径写法(明确指出)
fopen("C:\\2012_code\\84\\test\\test1.txt ","r");
文件使用方式 | 含义 | 如果指定文件不存在 |
---|---|---|
“r”(只读) | 为了输入数据,打开一个已存在的文本文件 | 出错 |
“w”(只写) | 为了输出数据,打开一个文本文件 | 建立一个新的文件(销毁原来的文件信息) |
“a”(追加) | 向文本文件尾添加数据 | 出错 |
“rb”(只读) | 为了输入数据,打开一个二进制文件 | 出错 |
“wb”(只写) | 为了输出数据,打开一个二进制文件 | 建立一个新的文件(销毁原来的文件信息) |
“ab”(追加) | 向一个二进制文件添加数据 | 出错 |
“r+”(读写) | 为了读和写,打开一个文本文件 | 出错 |
“w+”(读写) | 为了读和写,建立一个新的文件 | 建立一个新的文件 |
“a+”(读写) | 打开一个文件,在文件尾进行读写 | 建立一个新的文件 |
如果文件打开失败,返回空指针NULL
FILE* pf = fopen("text.txt","r");
if(pf == NULL)
{
printf("%s\n",strerror(errno));
return 0;
}
fclose(pf);
pf = NULL;
关闭文件时是值传递,不会改变文件本身。
结合MSDN食用更好
功能 | 函数名 | 适用于 |
---|---|---|
字符输入函数 | int fgetc( FILE * stream); | 所有输入流 |
字符输出函数 | int fputc(int c, FILE* stream); | 所有输出流 |
文本行输入函数 | char *fgets(char* string, int n, FILE* stream) | 所有输入流 |
文本行输出函数 | int fputs(const char* string, FILE* stream) | 所有输出流 |
格式化输入函数 | fscanf 把文件假想成黑色的对话框。和普通的scanf相比,前面多了一个指向文件信息的指针。 | 所有输入流 |
格式化输出函数 | fprintf 和普通的printf相比,前面多了一个指向文件信息的指针。(把数据放到文件里了) | 所有输出流 |
二进制输入 | fread : 返回类型是读了几个元素 | 文件 |
二进制输出 | fwrite | 文件 |
键盘stdin
和屏幕stdout
都是外部设备, stdin
和stdout
都是FILE类型的
键盘 - 标准输入设备; 屏幕 - 标准输出设备
是一个程序默认打开的两个流设备。
fread
的返回值fread returns the number of full items actually read, which may be less than count if an error occurs or if the end of the file is encountered before reaching count. Use the feof or ferror function to distinguish a read error from an end-of-file condition. If size or count is 0, fread returns 0 and the buffer contents are unchanged.
scanf
和printf
:针对标准输入流、标准输出流的格式化输入、输出语句
fscanf
和fprintf
:针对所有输入流、所有输出流的格式化输入、输出语句
sscanf
和sprintf
:
sscanf
:从字符串中读取格式化的数据
Read formatted data from a string.
int sscanf( const char *buffer, const char *format [, argument ] ... );
sprintf
:把格式化的数据存储到字符串中
Write formatted data to a string.
int sprintf( char *buffer, const char *format [, argument] ... );
用途:记录日志
但是文件不安全,不够高效 ------>>>> 数据库 MySQL ?
使用文件的格式:
打开文件 — 安全检查 ---- 操作 ---- 关闭文件
fseek
根据文件指针的位置和偏移量定位文件指针。
fseek
Moves the file pointer to a specified location.
int fseek( FILE *stream, long offset, int origin );
offset: 偏移量(单位字节) origin:文件指针当前位置
文件当前位置的三种形式:
SEEK_CUR
Current position of file pointer
SEEK_END
End of file
SEEK_SET
Beginning of file
ftell
返回文件指针相对于起始位置的偏移量。
ftell
Gets the current position of a file pointer.
long ftell( FILE *stream );
应用
int main() { FILE* pf = fopen("test.txt","r"); if(pf == NULL) { printf("%s\n",strerror(errno)); } //1.定位文件指针 fseek(pf, 2, SEEK_CUR); //2.读取文件 int ch = fgetc(pf); printf("%c",ch); fclose(pf); pf=NULL; return 0; }
rewind
:让文件指针回到起始位置
rewind
Repositions the file pointer to the beginning of a file.
void rewind( FILE *stream );
在文件读取过程中,不能用feof
函数的返回值直接用来判断文件是否结束。
Return Value
The feof
function returns a nonzero value after the first read operation that attempts to read past the end of the file. It returns 0 if the current position is not end of file. There is no error return.
而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。
文本文件读取是否结束,判断返回值是否为EOF
(fgetc
),或者NULL
(fgets
)
fgetc判断是否是EOF
, fget
s判断返回值是否为NULL
。
二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。比如:通过fread
判断返回值是否小于实际要读的个数。
perror()
函数直接先打印你放在括号里面的字符串,然后接着打印冒号和错误信息。
ferror()
Return Value
If no error has occurred on stream, ferror returns 0. Otherwise, it returns a nonzero value.
应用
int main() { FILE* pf = fopen("test.txt","r"); if(pf == NULL) { perror("open file test2.txt"); return 0; } //读文件 int ch = 0; while((ch = fgetc(pf)) != EOF) { putc(ch); } if(ferror(pf)) { printf("error\n"); } else if(feof(of)) { printf("end of file"); } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。