C语言重点难点精讲C语言文件
Posted 我擦了DJ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言重点难点精讲C语言文件相关的知识,希望对你有一定的参考价值。
文章目录
一:文件相关概念
(1)什么是文件
我们在磁盘上所见到的都是文件,在程序设计中,所谈到文件主要有两种:
- 一种是程序文件:包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe);
- 另一种是数据文件:文件的内容不一定是程序,也可以是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件
本节主要讨论的是数据文件
(2)文件名
一个文件有“文件路径+文件主干+文件后缀”三部分组成,为了方便起见,文件表示也被称为文件名
(3)文件类型
数据文件可以被分为文本文件和二进制文件
- 举个例子,程序里有个变量是10000,如果要把它放到磁盘里,你想要让用户读懂那么你肯定要用字符表示,也就是1对应的ASCII码,2对应的ASCII码,这样去转换,那么这种就是文本。如果不经过任何转换,就是二进制文件(使用记事本方式打开exe文件时的乱码)
如下程序代码表示将数字10000用存储为二进制文件
int main()
{
int a = 10000;
FILE* pf = fopen("test.txt", "wb");
fwrite(&a, 4, 1, pf);//二进制写
fclose(pf);
pf = NULL;
return 0;
}
虽然显示的是txt文件,但是其本质是二进制文件,所以用记事本打开是乱码
要去看到到底是什么,可以用VS,使用二进制编辑器打开
二:文件指针
每一个使用的文件,在内存中都会开辟一个文件信息区,这个文件信息区存放的是文件的名字,文件的状态等等,所有的这些信息存放在一个结构体变量中,将其取名为FILE
既然它是结构体变量,那么我们就可以创建一个指针去操作它,这个指针也就被称为文件指针
FILE* pf;//文件指针
pf是一个指向FILE类型的数据变量,可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就可以访问该文件
三:文件的打开和关闭
文件读写时先打开文件,再关闭文件
在打开文件的时候,会返回一个File*
的指针,C语言规定使用fopen
打开文件,fclose
关闭文件
FILE* fopen(const char* filename,const char* mode);
int fclose(FILE* stream)
mode
选项有如下几种
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL) {
printf("%s\\n", strerror(errno));
return 0;
}
fclose(pf);
pf == NULL;
return 0;
}
四:文件的顺序读写
读写函数如下
注意标准输入流和标准输入流
int main()
{
char arr[1024] = { 0 };
fgets(arr, 1024, stdin);//键盘就是标准输入流
fputs(arr, stdout);//屏幕是标准输出流
}
注意这几组函数
scanf
和printf
是针对标准输入/输出流的格式化输入/输出语句fscanf
和fprintf
是针对所有输入/输出流的格式化输入/输出语句sscanf
是从字符串中读取格式化的数据sprintf
是把格式化数据输出到字符串
(1)写
1:字符输出
int main()
{
FILE* pfwrite = fopen("test.txt", "w");
if (pfwrite == NULL) {
printf("%s\\n", strerror(errno);
return 0;
}
fputc('L', pfwrite);
fputc('o', pfwrite);
fputc('v', pfwrite);
fputc('E', pfwrite);
fclose(pfwrite);
pfwrite = NULL;
return 0;
}
2:文本行输出,其中换行需要手动加入
int main()
{
FILE* pfwrite = fopen("test.txt", "w");
if (pfwrite == NULL) {
printf("%s\\n", strerror(errno));
return 0;
}
fputs("I\\n", pfwrite);
fputs("LOVE\\n", pfwrite);
fputs("YOU", pfwrite);
return 0;
}
3:格式化输出
struct S
{
int n;
float score;
char arr[10];
};
int main()
{
struct S s = { 100,3.14f,"love" };
FILE* pfwrite = fopen("test.txt", "w");
if (pfwrite == NULL) {
printf("%s\\n", strerror(errno));
return 0;
}
fprintf(pfwrite, "%d-%f-%s", s.n, s.score, s.arr);//格式化输出
return 0;
}
4:二进制输出
struct S
{
char arr[10];
int age;
};
int main()
{
struct S s = { "Bob",19};
FILE* pfwrite = fopen("test.txt", "wb");//二进制
if (pfwrite == NULL) {
printf("%s\\n", strerror(errno));
return 0;
}
fwrite(&s, sizeof(struct S), 1, pfwrite);
return 0;
}
(2)读
1:字符读入
int main()
{
FILE* pfread = fopen("test.txt", "r");
if (pfread == NULL) {
printf("%s\\n", strerror(errno));
return 0;
}
printf("%c", fgetc(pfread));
printf("%c", fgetc(pfread));
printf("%c", fgetc(pfread));
printf("%c", fgetc(pfread));
printf("%c", fgetc(pfread));
return 0;
}
2:文本行输入,可以获得换行符
int main()
{
FILE* pfread = fopen("test.txt", "r");
if (pfread == NULL) {
printf("%s\\n", strerror(errno));
return 0;
}
char a[20];
fgets(a, 6, pfread);//读一行6个字符
printf("%s\\n", a);
return 0;
}
3:格式化输入
struct S
{
int n;
float score;
char arr[10];
};
int main()
{
struct S s = { 0 };
FILE* pfread = fopen("test.txt", "r");
if (pfread == NULL) {
printf("%s\\n", strerror(errno));
return 0;
}
fscanf(pfread, "%d%f%s", &(s.n), &(s.score), &(s.arr));
printf("%d-%f-%s", s.n, s.score, s.arr);
return 0;
}
4:二进制输入
int main()
{
struct S s = { 0 };
FILE* pfread = fopen("test.txt", "rb");//二进制
if (pfread == NULL) {
printf("%s\\n", strerror(errno));
return 0;
}
fread(&s, sizeof(struct S), 1, pfread);
printf("%d-%f-%s", s.n, s.score, s.arr);
return 0;
}
五:文件的随机读取
(1)fseek
文件指针开始会指向文件内容的开头,顺序读取时想要读取某个特定字符时,必须先读其前面的字符,而使用随机读取,可以直接偏移文件指针,直接读取
需要注意,在读取完成后文件指针会自动向后偏移
SEEL_CUR
:以文件指针的当前位置偏移SEEK_END
:以文件的末尾位置偏移SEEK_SET
:以文件的起始位置开始
int main()
{
FILE* pfread = fopen("test.txt", "r");
if (pfread == NULL) {
printf("%s\\n", strerror(errno));
return 0;
}
fseek(pfread, 2, SEEK_CUR);//以当前位置偏移整数
printf("%c\\n", fgetc(pfread));
return 0;
}
(2)ftell
返回当前文件指针相对于起始位置的偏移量
int main()
{
FILE* pfread = fopen("test.txt", "r");
if (pfread == NULL) {
printf("%s\\n", strerror(errno));
return 0;
}
fgetc(pfread);//读取一个跳过一个
int pos = ftell(pfread);
printf("%d\\n", pos);
fclose(fread);
return 0;
}
(3)rewind
让文件指针回到起始位置
int main()
{
FILE* pfread = fopen("test.txt", "r");
if (pfread == NULL) {
printf("%s\\n", strerror(errno));
return 0;
}
fgetc(pfread);//读取一个跳过一个
int pos1 = ftell(pfread);
rewind(pfread);//回到其实位置
int pos2 = ftell(pfread);
printf("%d\\n", pos2);//结果仍然是0
fclose(fread);
return 0;
}
六:文件结束条件判定
对于fgetc
,如果其返回值为EOF
;对于fgets
,如果其返回值为NULL
,就代表文件读到末尾
需要特别注意的一点是千万不要用feof判断文件结束
下面是读到文件末尾的标准写法
while ((c = fgetc(fp)) != EOF)
{
//操作
}
以上是关于C语言重点难点精讲C语言文件的主要内容,如果未能解决你的问题,请参考以下文章