有时候我们想通过编程语言来操作外部文件,对外部文件进行读取和修改、或者创建文件以此达到想要的目的。对此,我通过这篇文章来介绍如何通过C语言来操作文本文件。
文本文件是一种计算机文件,它是一种典型的顺序文件,其文件的逻辑结构又属于流式文件。特别的是,文本文件是指以ASCII码方式(也称文本方式)存储的文件,更确切地说,英文、数字等字符存储的是ASCII码,而汉字存储的是机内码。文本文件中除了存储文件有效字符信息(包括能用ASCII码字符表示的回车、换行等信息)外,不能存储其他任何信息。
平时我们可以打开记事本或者文档来直接写入内容,然后保存起来,这就成功创建了一个文本文件,那么怎么通过C语言来去创建并且写入内容呢?下面是相关文本函数的简介。
标准头文件:#include<stdio.h>
这里我的文件相对路径是 text.txt
函数:
FILE *fopen(char *filename, *type);
*type是表示操作编码,比如 r 表示对文件的读取、w 表示对文件的写入
示例:
FILE *fp;
fp=fopen("text.txt","r");//表示对文件的读取
读取的操作:fopen("text.txt","r");
原型:int fgetc( FILE *stream );
返回值:如果读取成功就返回一个读取的字符(类似于getchar),直到读取完成返回EOF(阿斯克码数值为-1)表示结束。每次是读取一个字符,读取完成后,文件指针向后移动一个位置。
示例如下:
已知我的文件内容
#include<stdio.h>
#include<stdlib.h>//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 );
#include<stdio.h>
#include<stdlib.h>//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 ... );
返回值:返回包括读取成功转换并且分配的字段数,如果读取错误或者读取到文件的末尾就返回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 );
返回值:
fread
返回函数读取的完整项数,该数目可能小于count
发生错误的情况,或者在到达count
之前遇到文件的末尾。
#include<stdio.h>
#include<stdlib.h>//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<string.h>
fread(a, 1, 6, fp);
printf("%s", a);
fread函数是一个非常灵活的函数,我们可以用它来自定义读取文件字符的个数类型等等。
fclose(fp);//fp是文本地址 FILE *fp
写入的操作:fopen("text.txt","w");
注意事项:写入文件后要关闭文件,否则文件内容可能会丢失。
原型:int fputc( int c, FILE *stream );
返回值:返回值是写入的一个字符,当返回EOF表示一个错误,结束写入。
注意:写入内容后,之前的内容会被销毁。
#include<stdio.h>
#include<stdlib.h>//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 );
返回值:如果每个函数成功,则返回非负值,即写入的字符串。 发生错误时,
fputs
将返回EOF。
示例:
fputs("china", fp);
//或者
char s[10];
scanf("%s,s);
fputs(s, fp);
原型:int fprintf( FILE *stream, const char *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 );
返回值:
fwrite
返回函数写入的完整项数,这可能小于count
发生错误的情况。
#include<stdio.h>
#include<stdlib.h>//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)
功能:将文本文件的指针返回到文本的开始位置。
示例:
原型:int fseek( FILE *stream, long offset, int origin );
功能:我们可以通过fseek函数来初始化指针的位置,然后进行读取或者写入。
origin 初始位置的值如下,及其相应的功能
示例:怎么去读取最后一行的字符串?
已知文件的内容:
#include<stdio.h>
#include<stdlib.h>//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);
}
结果如下:
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- bangwoyixia.com 版权所有 湘ICP备2023022004号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务