C语言之文件操作 -----Day19
一. 知识点整理
1. C文件
1.1 C文件概述
- 文件
指一组相关数据的有序集合。这个数据集有一个名称,叫做文件名。实际上在前面的各章中我们已经多次使用了文件,例如源程序文件、目标文件、可执行文件、库文件 (头文件)等。
1.2 C文件的分类
- 从用户观点
特殊文件和普通文件(磁盘文件)
- 从操作系统看
输入文件:终端键盘
输出文件:显示屏和打印机
- 按数据的组织形式
ASCLL文件:每一个字节存放一个ASCLL代码
二进制文件:把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放
1.3 文件的操作
1.3.1 文件打开和关闭
- 定义文件型指针变量
FILE *fp;
- 打开文件——fopen函数
fp = fopen(文件名, 使用文件方式);
- 文件使用方式
- 注意几点:
- 用"r"时,文件必须已经存在,并且只能读,不能修改
- 用“w”打开的文件只能向该文件写入。若打开的文件不存在,则以指定的文件名建立该文件,若打开的文件已经存在,则将该文件删去,重建一个新文件。
- 若要向一个已存在的文件追加新的信息,只能用“a”方式打开文件。如果文件不存在,则新建一个文件
- 关闭文件——fclode函数
使文件指针变量不指向该文件,也就是文件指针变量与文件“脱钩”,此后不能再通过该指针对原来与其相联系的文件进行读写操作,关闭成功返回值为0;否则返回EOF(-1)
1.3.2 文件的读写
- 字符输入输出函数
- fputc(ch, fp);
将字符(ch的值)输出到fp所指向的文件去
fputc函数有一个返回值,如写入成功则返回写入的字符,否则返回一个EOF。可用此来判断写入是否成功。
- ch = fgetc(fp);
从打开的文件 fp 中读取一个字符并送入 ch 中
在fgetc函数调用中,读取的文件必须是以读或读写方式打开的
在文件打开时,该指针总是指向文件的第一个字节。使用fgetc 函数后,该位置指针将向后移动一个字节。因此可连续多次使用fgetc函数,读取多个字符。
- 字符串读写函数
- fgets(str, n, fp);
从fp所指的文件中读出n-1个字符送入字符数组str中,因为在最后加一个’\0’
- fputs(“str1”, fp);
意义是把字符串“str1”写入fp所指的文件之中。
- 数据块的读写函数
- fread (buffer, size, count, fp);
- fwrite(buffer, size, count, fp);
说明
buffer:是一个指针。
对fread 来说,它是读入数据的存放地址。
对fwrite来说,是要输出数据的地址(均指起始地址)。
size: 要读写的字节数。
count: 要进行读写多少个size字节的数据项。
fp: 文件型指针。
- fseek函数
- fseek(文件类型指针,位移量,起始点)
文件开头 SEEK_SET 0
文件当前位置 SEEK_CUR 1
文件末尾 SEEK_END 2
- 应用举例
fseek(fp,100L,0);
将位置指针移到离文件头100个字节处
fseek(fp,50L, 1);
将位置指针移到离当前位置50个字节处
fseek(fp,50L, 2);
将位置指针从文件末尾处向后退10个字节
fseek(fp,isizeof(struct stu),0);
将位置指针移到离文件头isizeof(struct stu)这个距离处。
二. 疑难点总结
1. 区别和总结printf、sprintf、fprintf与scanf、sscanf、fscanf的区别?
printf:用于格式化后的字符串的输出
sprintf:用于格式化并且输出到指定的字符串中,列如:sprintf(buffer, “%d”, 123456);执行后buffer即指向字符串“123456”
fprintf:用于格式化并且输出到指定的文件中去
scanf:获取用户输入的数据并进行自动匹配
sscanf:可以获取字符串中的整数、浮点数和字符串等等
fscanf:可以获取文件中的整数、浮点数和字符串等等
2.什么是标准输入(stdin)、标准输出(stdout)?
在Linux系统下,我们可以知道一切设备都是文件,所以stdin和stdout其实是/dev/路径下的文件;stdin就是从外部设备输入到内存,stdout就是从内存输出到外部设备,他们是用于IO口的外部设备,也就是输出到屏幕。
3. 怎样实现文件的逆序输出
#include <stdio.h>
int main()
{
FILE *fp1, *fp2;
int flag = 1;
char ch;
fp1 = fopen("test1.txt", "w");
fputs("123456\n0123456\n", fp1);
fclose(fp1);
fp2 = fopen("test2.txt", "w");
fp1 = fopen("test1.txt", "r");
while (fseek(fp1, -flag, SEEK_END) != EOF)
{
ch = fgetc(fp1);
fputc(ch, fp2);
flag++;
}
fclose(fp1);
fclose(fp2);
}
4.实现文件的拷贝
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
FILE *fp1, *fp2;
char ch;
if (argc == 1)
{
printf("没有输入文件!\n");
exit(0);
}
if ((fp1 = fopen(argv[1], "r")) == NULL)
{
printf("%s文件打开失败!\n",argv[1]);
exit(0);
}
if (argc == 2)
{
fp2 = stdout;
}
else if ((fp2 = fopen(argv[2],"w")) == NULL)
{
printf("%s文件打开失败!\n", argv[2]);
exit(0);
}
while ((ch = fgetc(fp1)) != EOF)
{
fputc(ch, fp2);
}
fclose(fp1);
fclose(fp2);
}
三. 自我总结
文件和链表学习完之后,我最大的感受就是难度一下就飙升,尤其是链表,文件的知识点也比较多。由于对文件的知识掌握的不好,所以在一些操作上老是会出现一些问题,自己很崩溃,希望自己能尽快克服当前的压力,成长起来。