目录
文本文件相关介绍
1.打开文件
2.文件的读取
(1) fgetc 函数
(2)fgets 函数
(3)fscanf 函数
(4)fread 函数
3.关闭文件
fclose(FILE *stream );
4.文件的写入
(1)fpuc 函数
(2)fputs 函数
(3)fprintf 函数
(4)fwrite 函数
5.文本文件的指针定位
(1)rewind 函数
(2)fseek 函数
有时候我们想通过编程语言来操作外部文件,对外部文件进行读取和修改、或者创建文件以此达到想要的目的。对此,我通过这篇文章来介绍如何通过C语言来操作文本文件。
文本文件是一种计算机文件,它是一种典型的顺序文件,其文件的逻辑结构又属于流式文件。特别的是,文本文件是指以ASCII码方式(也称文本方式)存储的文件,更确切地说,英文、数字等字符存储的是ASCII码,而汉字存储的是机内码。文本文件中除了存储文件有效字符信息(包括能用ASCII码字符表示的回车、换行等信息)外,不能存储其他任何信息。
文本文件常用格式:
(1).txt 纯文字文档,不携带字体的颜色、类型、以及相关修饰格式。
(2).doc 是Microsoft Word创建的格式化文件,一般用于图文排版。
(3).pdf 具有良好的加密性,一般多用于企业办公。
(4).doc与.docx .doc文件是旧版World文档旧版文件格式,.docx是新版格式。
(5).ASCLL 指含有用标准ASCII字符集编码的字符的数据和文本文件。
平时我们可以打开记事本或者文档来直接写入内容,然后保存起来,这就成功创建了一个文本文件,那么怎么通过C语言来去创建并且写入内容呢?下面是相关文本函数的简介。
标准头文件:#include
这里我的文件相对路径是 text.txt
函数:
FILE *fopen(char *filename, *type);
这个函数是返回一个指针类型,如果文本读取成功就返回文本的地址,如果读取失败就返回NULL空指针。
*type是表示操作编码,比如 r 表示对文件的读取、w 表示对文件的写入
示例:
FILE *fp;
fp=fopen("text.txt","r");//表示对文件的读取
读取的操作:fopen("text.txt","r");
原型:int fgetc( FILE *stream );
返回值:如果读取成功就返回一个读取的字符(类似于getchar),直到读取完成返回EOF(阿斯克码数值为-1)表示结束。每次是读取一个字符,读取完成后,文件指针向后移动一个位置。
示例如下:
已知我的文件内容
#include
#include//exit()函数的头文件
int main()
{
FILE* fp;
fp = fopen("text.txt", "r");
if (feof(fp))
{
printf("NULL");
exit(0);//表示如果读取为空文件就正常退出
}
char a;
a = fgetc(fp);
printf("%c", a);//在控制台输出读取的字符
}
fgetc函数每次是读取一个字符,读取完成后文件指针向后移动一个位置,当下一次读取就是第二个字符对此我们可以通过循环来实现文件内容的全部读取。例如:
char a;
for(; (a = fgetc(fp))!=EOF;)
printf("%c", a);
原型:char *fgets( char *str, int numChars, FILE *stream );
参数:str表示字符串的地址,numChars表示要读取字符最大个数,stream表示文件的地址
返回值:将文件的字符传入到字符串str的地址,然后返回str地址。
#include
#include//exit()函数的头文件
int main()
{
FILE* fp;
fp = fopen("text.txt", "r");
if (feof(fp))
{
printf("NULL");
exit(0);//表示如果读取为空文件就正常退出
}
char s[100];
fgets(s, 10, fp);//最大读取10个
printf("%s", s);
}
原型:int fscanf( FILE *stream, const char *format , argument ... );
参数:steam是文件地址,format是表示输出的参数,argument是表示输出的内容。
返回值:返回包括读取成功转换并且分配的字段数,如果读取错误或者读取到文件的末尾就返回EOF。
读取输出字符串:
char s[100];
fscanf(fp, "%s", s);//将读取的内容导入字符串s的地址
printf("%s", s);
读取输出单个字符:
char a;
fscanf(fp, "%c", &a);//读取单个字符导入a的地址
printf("%c", a);
读取输出整数:
int b;
fscanf(fp, "%d", &b);
printf("%d", b);
fscanf是一个比较通用的函数,可以输出单个字符,多个字符,整形等。
原型:size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
参数:buffer表示读取的类型的地址,size_t size表示读取需要的字节数,size_t count表示读取的个数,stream表示文本文件地址
返回值:
fread
返回函数读取的完整项数,该数目可能小于count
发生错误的情况,或者在到达count
之前遇到文件的末尾。
#include
#include//exit()函数的头文件
int main()
{
FILE* fp;
fp = fopen("text.txt", "r");
if (feof(fp))
{
printf("NULL");
exit(0);//表示如果读取为空文件就正常退出
}
//魔鬼细节:使用fread函数读取有限个字符要对字符串进行初始化,也就是给字符串加上终止符
char a[7] = { 0 };//实际上我要读取6个字符,但是我初始化要7个,最后一个是表示终止符
fread(a, sizeof(char), 6, fp);
printf("%s", a);
}
char a[7] ;
memset(a, 0, sizeof(a));//我们还可以通过memset 函数来进行初始化,其头文件是#include
fread(a, 1, 6, fp);
printf("%s", a);
fread函数是一个非常灵活的函数,我们可以用它来自定义读取文件字符的个数类型等等。
stream是文本文件地址
fclose(fp);//fp是文本地址 FILE *fp
写入的操作:fopen("text.txt","w");
注意事项:写入文件后要关闭文件,否则文件内容可能会丢失。
原型:int fputc( int c, FILE *stream );
参数:c表示要写入的字符,stream表示文件地址。
返回值:返回值是写入的一个字符,当返回EOF表示一个错误,结束写入。
注意:写入内容后,之前的内容会被销毁。
#include
#include//exit()函数的头文件
int main()
{
FILE* fp;
fp = fopen("text.txt", "w");
if (feof(fp))
{
printf("NULL");
exit(0);//表示如果读取为空文件就正常退出
}
fputc('s', fp);//写入一个字符s
fclose(fp);
}
此时会发现运行结果控制台是没有什么显示的,我们可以去打开text文本文件去查看结果
//类似于fgetc函数,我们也可以用循环来写入多字字符
char ch[10];
scanf("%s", ch);
for (int i = 0; ch[i]!='\0'; i++)
fputc(ch[i], fp);
原型:int fputs( const char *str, FILE *stream );
参数:str表示字符串,stream表示文件地址
返回值:如果每个函数成功,则返回非负值,即写入的字符串。 发生错误时,
fputs
将返回EOF。
示例:
fputs("china", fp);
//或者
char s[10];
scanf("%s,s);
fputs(s, fp);
原型:int fprintf( FILE *stream, const char *format , argument ... );
参数:steam是文件地址,format是表示输出的参数,argument是表示输出的内容。
返回值:
fprintf
返回已写入的字节数,如果输入错误就返回EOF表示输入结束。
for(int i=0;i<10;i++)
fprintf(fp, "%d", i);//写入0~9
//字符串写入
char ch[20];
scanf("%s", ch);
fprintf(fp, "%s", ch);
原型:size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
参数:buffer表示读取的类型的地址,size_t size表示读取需要的字节数,size_t count表示读取的个数,stream表示文本文件地址。
返回值:
fwrite
返回函数写入的完整项数,这可能小于count
发生错误的情况。
#include
#include//exit()函数的头文件
int main()
{
FILE* fp;
fp = fopen("text.txt", "w");
if (feof(fp))
{
printf("NULL");
exit(0);//表示如果读取为空文件就正常退出
}
int a[10];
for (int i = 0; i < 10; i++)//写入10个数字的数组
scanf("%d", &a[i]);
for (int i = 0; i < 10; i++)
fwrite(&a[i],sizeof(int),1,fp);
}
别惊讶,写入的结果不是数字,因为fwrite写入的内容会转换成阿斯克码字符,随机数在文件里面显示的应该是字符,而不是数字,所以会出现这些识别不了的符号。
原型:void rewind(FILE *stream)
参数:stream是文件地址.
功能:将文本文件的指针返回到文本的开始位置。
示例:
原型:int fseek( FILE *stream, long offset, int origin );
参数:stream文本地址,offset表示移动的字节数(正数表示指针往右移,负数表示往左移), origin表示初始位置。
功能:我们可以通过fseek函数来初始化指针的位置,然后进行读取或者写入。
示例:怎么去读取最后一行的字符串?
已知文件的内容:
#include
#include//exit()函数的头文件
int main()
{
FILE* fp;
fp = fopen("text.txt", "r");
if (feof(fp))
{
printf("NULL");
exit(0);//表示如果读取为空文件就正常退出
}
char a='a';
fseek(fp, -1, SEEK_END);//把文件指针移动到文本末尾
for (;a!='\n';)
{
a = fgetc(fp);//依次读取
fseek(fp, -sizeof(char), SEEK_CUR);//由于每次读取了一个字符,文件指针会往后移动一个位置,所以要-2,从而实现在原先的基础上往上移动一个位置
}
fseek(fp,2, SEEK_CUR);//最后一次移动是在'\n'上面两个(字节)位置,所以要在次基础上向后移动两个位置
char s[200] = { 0 };
fgets(s,200, fp);
puts(s);
fclose(fp);
}
结果如下: