C语言文件操作
Posted Ja_King_ZH
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言文件操作相关的知识,希望对你有一定的参考价值。
文件操作
1.文件的打开和关闭
1.1 文件的打开
#include <malloc.h>
#include <stdio.h>
// 主函数
int main()
{
FILE *fp; // 文件指针
fp = fopen("input.txt","r"); // 打开文件
read/write fucntions // 读或者写函数
fclose(fp); // 关闭文件指针
return 0;
}
(1)用“r”方式打开的文件只能用于向计算机输入而不能用作向该文件输出数据,而且该文件应该已经存在,不能用“r”方式打开一个并不存在的文件(即输入文件),否则出错。
(2)用“w”方式打开的文件只能用于向该文件写数据(即输出文件),而不能用来向计算机输入。如果原来不存在该文件,则在打开时新建立一个以指定的名字命名的文件。如果原来已存在一个以该文件名命名的文件,则在打开时将该文件删去,然后重新建立一个新文件。
(3)如果希望向文件末尾添加新的数据(不希望删除原有数据),则应该用“a”方式打开。但此时该文件必须已存在,否则将得到出错信息。打开时,位置指针移到文件末尾。
(4)用“r+”、“w+”、 “a+”方式打开的文件既可以用来输入数据,也可以用来输出数据。用“r+”方式时该文件应该已经存在,以便能向计算机输入数据。用“w+”方式则新建立一个文件,先向此文件写数据,然后可以读此文件中的数据。用“a+”方式打开的文件,原来的文件不被删去,位置指针移到文件末尾,可以添加,也可以读。
(5)如果不能实现“打开”的任务,fopen函数将会带回一个出错信息。出错的原因可能是用“r”方式打开一个并不存在的文件;磁盘出故障;磁盘已满无法建立新文件等。此时fopen函数将带回一个空指针值NULL。
(6)在向计算机输入文本文件时,将回车换行符转换为一个换行符,在输出时把换行符转换成为回车和换行两个字符。在用二进制文件时,不进行这种转换,在内存中的数据形式与输出到外部文件中的数据形式完全一致,一一对应。
(7)在程序开始运行时,系统自动打开3个标准文件:标准输入、标准输出、标准出错输出。这3个文件都与终端相联系。因此以前所用到的从终端输入或输出都不需要打开终端文件。系统自动定义了3个文件指针stdin、stdout和stderr,分别指向终端输入、终端输出和标准出错输出(也从终端输出)。如果程序中指定要从stdin所指的文件输入数据,就是指从终端键盘输入数据。
1.2 文件的关闭
在使用完一个文件后应该关闭它,以防止它再被误用。“关闭”就是使文件指针变量不指向该文件,也就是文件指针变量与文件“脱钩”,以后不能再通过该指针对原来与其相联系的文件进行读写操作。除非再次打开,使该指针变量重新指向该文件。
2.文件的读写
2.1 写字符函数fputc和读字符函数fgetc
1、从键盘输入一些字符,逐个把它们送到磁盘上去,直到输入一个“#”为止
#include <stdio.h>
#include <stdlib.h>
// 主函数
int main(int argc, char *argv[]) // *argv[]:指针数组
{
FILE *fp;
fp = fopen("input.txt", "r");
if (fp == NULL)
{
exit(1);
}
char c;
c = fgetc(fp);
while (c != EOF)
{
putchar(c);
c = fgetc(fp);
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
// 主函数
int main(int argc, char *argv[]) // *argv[]:指针数组
{
FILE *fp;
char filename[10]; //文件名
printf("input file name: ");
scanf("%s", &filename);
if ((fp = fopen(filename, "w")) == NULL)
{
exit(1);
}
fflush(stdin); // 将缓冲区内的数据写回参数stream指定的文件中
printf("input character\\n");
char c;
c = getchar(); // 输入字符
while (c != '#') // 判别
{
fputc(c, fp);
c = getchar();
}
return 0;
}
2.2 写字符串函数fputs和读字符串函数fgets
1、将学生数据,由键盘输入并存储到磁盘文件中
#include <stdio.h>
#include <stdlib.h>
// 主函数
int main(int argc, char *argv[]) // *argv[]:指针数组
{
FILE *fp;
char student[50]; // 创建字符数组-存储输入的字符串
printf("input filename:");
scanf("%s", student);
if ((fp = fopen("input.txt", "w")) == NULL)
{
exit(1);
}
for (int i = 0; i < 3; i++)
{
gets(student); // 获取输入的字符串
fputs(student, fp);// 存储到文件fp
fputs("\\n", fp);
}
fclose(fp);
return 0;
}
2、从上例文件中读取学生数据,并显示在屏幕上
#include <stdio.h>
#include <stdlib.h>
// 主函数
int main(int argc, char *argv[]) // *argv[]:指针数组
{
FILE *fp;
if ((fp = fopen("input.txt", "r")) == NULL)
exit(0);
char string[80];
while (fgets(string, 80, fp) != NULL)
{
printf("%s", string);
}
fclose(fp);
return 0;
}
2.3 格式化写函数fprintf和格式化读函数fscanf
1、将学生数据,由键盘输入并存储到磁盘文件中
#include <stdio.h>
#include <stdlib.h>
// 主函数
int main(int argc, char *argv[]) // *argv[]:指针数组
{
FILE *fp;
if ((fp = fopen("input.txt", "w")) == NULL)
exit(0);
long num;
char name[10];
int age;
for (int i = 0; i < 5; i++) {
printf("第%d个学生:\\n", i + 1);
printf("学号:\\n");
scanf("%ld", &num);
printf("姓名:\\n");
scanf("%s", &name);
printf("年龄:\\n");
scanf("%d", &age);
fprintf(fp, "学号:%ld 姓名:%9s 年龄:%d\\n", num, name, age);
}
fclose(fp);
return 0;
}
2、从上例文件中读取学生数据,并显示在屏幕上
#include <stdio.h>
#include <stdlib.h>
// 主函数
int main(int argc, char *argv[]) {
FILE *fp;
if ((fp = fopen("student.txt", "r")) == NULL)
exit(0);
long num;
char name[10];
int age;
while (!feof(fp)) {
// fprintf(fp, "学号:%ld 姓名:%9s 年龄:%d\\n", num, name, age);
fscanf(fp, "学号:%ld 姓名:%9s 年龄:%d\\n", &num, name, &age);
printf("%ld %s %d\\n", num, name, age);
}
fclose(fp);
return 0;
}
3.二进制文件的读写
3.1fread函数和fwrite函数
从键盘输入4个学生数据,然后把它们转存到磁盘文件上去,然后再从磁盘文件中一次性读入内存并显示出来
#include <stdio.h>
#include <stdlib.h>
struct student
{
long num;
char name[10];
int age;
} s[4];
// 主函数
int main(int argc, char *argv[])
{
FILE *fp;
if ((fp = fopen("student.dat", "w")) == NULL)
exit(0);
for (int i = 0; i < 4; i++)
{
printf("第%d个学生:\\n", i + 1);
printf("学号:\\n");
scanf("%ld", &s[i].num);
printf("姓名:\\n");
scanf("%s", s[i].name);
printf("年龄:\\n");
scanf("%d", &s[i].age);
}
fwrite(s, sizeof(struct student), 4, fp);
rewind(fp);
// for (int i = 0; i < 4; i++)
// {
// fread(&s, sizeof(struct student), 1, fp);
// printf("%ld %s %d\\n", s->num, s->name, s->age);
// }
fread(s, sizeof(struct student), 4, fp);
for (int i = 0; i < 4; i++)
{
printf("%ld %s %d\\n", s[i].num, s[i].name, s[i].age);
}
fclose(fp);
return 0;
}
3.2 文件的定位
文件中有一个位置指针,指向当前读写的位置。如果顺序读写一个文件,每次读写一个字符,则读写完一个字符后,该位置指针自动移动指向下一个字符位置。如果想改变这样的规律,强制使位置指针指向其他指定的位置,可以用有关函数。
3.3 fseek、ftell和rewind
fseek是随机读写函数,原型如下;
int fseek( FILE *stream, long offset, int origin );
第一个参数为文件指针,第二个参数为偏移量,第三个参数问指针当前位置。
ftell是计算当前指针相对于起始位置的偏移量,原型如下:
long ftell( FILE *stream );
rewind函数是返回至起始位置。
int main() {
FILE*pf=fopen("./date.txt", "r");
if (NULL == pf) {
perror("fopen");
return -1;
}
//随机读写
//文件中放着abcdef,如果第一次要读c,则需使用fseek
fseek(pf, 2, SEEK_SET);
char ch = fgetc(pf);
printf("%c", ch);
//计算指针相对于起始位置的偏移量
int ret = ftell(pf);
printf("%d", ret);
//让指针回到起始位置
rewind(pf);
fclose(pf);
pf = NULL;
return 0;
}
4.总结
以上是关于C语言文件操作的主要内容,如果未能解决你的问题,请参考以下文章
我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段
我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段