程序文件
包括源程序文件(后缀.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)
数据文件
文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件
文件名
一个文件要有一个唯一的文件标识,以便用户识别和引用
文件名包含三部分:文件路径+文件名主干+文件后缀
列如:C:\code\test.txt
为了方便起见,文件标识常被称为文件名
文件指针
缓冲文件系统中,关键的概念是“文件型指针”,简称“文件指针”
FILE * p;
定义p是一个指向FILE类型数据的指针变量。可以使得p指向某个文件的文件信息区。通过该文件信息区中的信息就能够访问该变量,
通过文件指针变量能够找到与他关联的文件
文件的打开和关闭
文件在读写前应该打开文件,在使用结束后应该关闭文件
//打开文件
FILE * fopen(const char * filename,const char * mode);
//关闭文件
int fclose(FILE * stream);
int main() {
FILE* p = fopen("test.txt", "w");
if (p == NULL)
{
perror("fopen");
return 1;
}
fclose(p);
return 0;
}
"r" | 只能从文件中读数据,该文件必须先存在,否则打开失败 |
"w" | 只能向文件写数据,若指定的文件不存在则创建它,如果存在则先删除它再重建一个新文件 |
"a" | 向文件增加新数据(不删除原有数据),若文件不存在则打开失败,打开时位置指针移到文件末尾 |
"r+" | 可读/写数据,该文件必须先存在,否则打开失败 |
"w+" | 可读/写数据,用该模式打开新建一个文件,先向该文件写数据,然后可读取该文件中的数据 |
"a+" | 可读/写数据,原来的文件不被删去,位置指针移到文件末尾 |
功能 | 函数名 | 适用于 |
---|---|---|
字符输入函数 | fgetc | 所有输入流 |
字符输出函数 | fputc | 所有输出流 |
文本行输入函数 | fgets | 所有输入流 |
文本行输出函数 | fputs | 所有输出流 |
格式化输入函数 | fscanf | 所有输入流 |
格式化输出函数 | fprintf | 所有输出流 |
二进制输入 | fread | 文件 |
二进制输出 | fwrite | 文件 |
流
C语言程序,只要运行起来,就默认打开了3个流;
stdin - 标准输入流 - 键盘
stdout - 标准输出流 - 屏幕
stderr - 标准输出流 - 屏幕
fgetc从文件流中读取数据
int main() {
int ret1 = fgetc(stdin);
printf("%c\n", ret1);
int ret2 = fgetc(stdin);
printf("%c\n", ret2);
int ret3 = fgetc(stdin);
printf("%c\n", ret3);
return 0;
}
fputs一行输入
int main() {
FILE* p = fopen("tste.txt", "w");
if (p == NULL)
{
perror("fopen");
return 1;
}
fputs("abcdef\n", p);
fputs("qwerty\n", p);
fclose(p);
p = NULL;
return 0;
}
fgets
int main() {
char arr[10] = { 0 };
FILE* p = fopen("tste.txt", "r");
if (p == NULL)
{
perror("fopen");
return 1;
}
fgets(arr,4,p);
printf("%s\n", arr);
fgets(arr, 4, p);
printf("%s\n", arr);
fclose(p);
p = NULL;
return 0;
}
fprintf
struct Student
{
char name[20];
int age;
char UID[20];
};
int main() {
struct Student s1 = { "abcd",20,"123456" };
FILE* p = fopen("test.txt", "w");
if (p == NULL)
{
perror("fopen");
return;
}
fprintf(p, "%s %d %s", s1.name, s1.age, s1.UID);
fclose(p);
return 0;
}
fscanf
struct Stu
{
char id[20];
char password[20];
};
int main() {
struct Stu s1;
FILE* p = fopen("test.txt", "r");
if (p == NULL)
{
perror("fopen");
return;
}
fscanf(p, "%s %s", &s1.id, &s1.password);
printf("%s %s", s1.id, s1.password);
fclose(p);
return 0;
}
fwrite fread
struct Student
{
char ID[20];
char PassWorld[20];
int age;
};
void Write()
{
struct Student s1 = { "123","abcd",20 };
FILE* p = fopen("test.txt", "w");
if (p == NULL)
{
perror("fopen");
return;
}
fwrite(&s1, sizeof(struct Student), 1, p);
fclose(p);
p = NULL;
}
void Read()
{
struct Student s1;
FILE* p = fopen("test.txt", "r");
if (p == NULL)
{
perror("fopen");
return;
}
fread(&s1, sizeof(struct Student), 1, p);
printf("%s %s %d", s1.ID, s1.PassWorld, s1.age);
fclose(p);
p = NULL;
}
int main() {
Write();
printf("\n");
Read();
return 0;
}
sprintf
把一个格式化的数据转换为字符串
struct Student
{
char name[20];
int age;
float data;
};
int main()
{
struct Student s1 = { "123",20,52 };
char string[50] = { 0 };
sprintf(string, "%s %d %lf", s1.name, s1.age, s1.data);
printf("%s\n", string);
return 0;
}
sscanf
把字符串还原出一个结构体数据
struct Student
{
char name[20];
int age;
float data;
};
int main()
{
struct Student s1 = { "123",20,52 };
char string[50] = { 0 };
struct Student s2[50] = {0};
sprintf(string, "%s %d %f", s1.name, s1.age, s1.data);
printf("%s\n", string);
sscanf(string, "%s %d %f", s1.name, &(s1.age), &(s1.data));
printf("%s\n", s1.name);
printf("%d\n", s1.age);
printf("%f\n", s1.data);
return 0;
}
文件的随机读写
fseek
根据文件指针的位置和偏移量来定文件指针
int main()
{
FILE* p = fopen("test.txt", "r");
int ch = fgetc(p);
printf("%c\n", ch);
fseek(p, -1, SEEK_CUR);
ch = fgetc(p);
printf("%c\n", ch);
fseek(p, -2, SEEK_END);
ch = fgetc(p);
printf("%c\n", ch);
fseek(p, 5, SEEK_SET);
ch = fgetc(p);
printf("%c\n", ch);
return 0;
}
ftell
返回文件指针相对于起始位置的偏移量
int ret = ftell(p);
rewind
让文件指针的位置回到文件的起始位置
rewind(p);
feof
当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束
文件读取结束的判定
fgetc函数在读取结束的时候,会返回EOF
正常读取的时候,返回的是读取到的字符的ASCII码值
fgets函数在读取结束的时候,会返回NULL
正常读取的时候,返回存放字符串的空间起始地址
fread 函数在读取的时候,返回的是实际读取到的完整元素的个数
如果发现读取到的完整的元素的个数小于指定的元素个数,这就是最后一次读取了。
feof()
feof()是检测流上的文件结束符的函数,如果文件结束,则返回非0值,否则返回0
一般在文件操作,中经常使用feof()判断文件是否结束。
if (feof(pread)) {
printf("文件正常结束");
}
else if (ferror(pread))
{
printf("文件读取失败");
}