今天向大家分享的是文件操作中文件的顺序读写以及随机读写的一些重难点问题。

目录
1.1字符输出函数(fputc)&&字符输入函数(fgetc)
1.2文本行输出函数(fputs)&&文本行输入函数(fgets)
1.3格式化输出函数(fprintf)&&格式化输入函数(fscanf)
1.5 二进制输出函数(fread)&&二进制输入函数(fwrite)
2.1 fseek:根据文件指针的位置和偏移量来定位文件指针

int fputc( int c, FILE *stream );
写入一个字符:
- int main()
- {
- FILE* pf = fopen("text.txt", "w");
- if (pf == NULL)
- {
- printf("%s\n", strerror(errno));
- return 0;
- }
- else//写入文件
- {
- fputc('b', pf);
- fputc('i', pf);
- fputc('t', pf);
- }
- fclose(pf);
- pf = NULL;
- return 0;
- }
其中打开文件用了fopen函数,关闭文件用了fclose函数.刚开始文件中并没有text.txt文件,由于fopen函数中第二个参数为"w"(具体可以看后面补充的图),所以它会自动建立了一个新文件,并用fputc函数将字符'b' 'i' 't'写入到了该文件夹中。

双击打开后里面存放的是bit

该函数的作用是一次将一个字符写入到新建立的文件夹中。
补充图:

读取一个字符:
int fgetc( FILE *stream );
- int main()
- {
- FILE* pf = fopen("text.txt", "r");
- if (pf == NULL)
- {
- printf("%s\n", strerror(errno));
- return 0;
- }
- else//读取文件
- {
- printf("%c", fgetc(pf));
- printf("%c", fgetc(pf));
- printf("%c", fgetc(pf));
- }
- fclose(pf);
- ps = NULL;
- return 0;
- }
由于刚才建立了文件夹text.txt,所以一个fgetc函数会将文件夹中一个字符读取出来:

在这儿我们还得了解一些常识:
所以我们可以用fgetc&&fputc在键盘上输入信息以及在屏幕上打印信息:

写入一行字符:
int fputs( const char *string, FILE *stream );
- int main()
- {
- FILE* pf = fopen("text.txt", "w");
- if (pf == NULL)
- {
- printf("%s\n", strerror(errno));
- return 0;
- }
- //写入文件
- fputs("hello\n", pf);
- fputs("world", pf);
-
- fclose(pf);
- pf = NULL;
- return 0;
- }
与fputc函数不同的是,该函数一次能写入一个字符串的数据到新建立的文件夹中:

读取一行字符:
char *fgets( char *string, int n, FILE *stream );
- int main()
- {
- FILE* pf = fopen("text.txt", "r");
- char buf[100]={0};
- if (pf == NULL)
- {
- printf("%s\n", strerror(errno));
- return 0;
- }
- //读取文件
- fgets(buf, 100, pf);
- puts(buf);
- fgets(buf, 100, pf);
- puts(buf);
- fclose(pf);
- pf = NULL;
- return 0;
- }
这里定义了一个buf数组,将pf指向文件中的字符串拷贝到buf数组中:

用stdin&&stdout来从键盘上输入一行字符以及从屏幕上打印一行字符:
- int main()
- {
- char buf[100] = { 0 };
- fgets(buf, 100, stdin);
- fputs(buf, stdout);
-
- //gets(buf);
- //puts(buf);
- return 0;
上述fgets和fputs与gets和puts效果差不多。
格式化输出函数(向文件中写入信息):
int fprintf( FILE *stream, const char *format [, argument ]...);
- struct stu
- {
- char name[10];
- char sex[5];
- int age;
- double weight;
- };
- int main()
- {
- struct stu s = { "lisi","男",18,60.0 };
- FILE* pf = fopen("text.txt", "w");
- if (pf == NULL)
- {
- printf("%s\n", strerror(errno));
- return 0;
- }
- fprintf(pf, "%s %s %d %lf", s.name, s.sex, s.age, s.weight);//向文件中输出信息
- fclose(pf);
- pf = NULL;
- return 0;
- }
从代码中可以看到:我们将s进行了初始化,想将该内容拷贝到text.txt文件夹中:

代码执行后可以明显发现文件夹中已经成功拷贝。
格式化输入函数(从文件中读取信息):
int fscanf( FILE *stream, const char *format [, argument ]... );
- struct stu
- {
- char name[10];
- char sex[5];
- int age;
- double weight;
- };
-
- int main()
- {
- struct stu s = { 0 };
- FILE* pf = fopen("text.txt", "r");
- if (pf == NULL)
- {
- printf("%s\n", strerror(errno));
- return 0;
- }
- fscanf(pf, "%s %s %d %lf", s.name, s.sex, &(s.age), &(s.weight));//从文件中获得信息
- printf("%s %s %d %lf", s.name, s.sex, s.age, s.weight);
- fclose(pf);
- pf = NULL;
- return 0;
- }
代码中我们对s的内容初始化为0,代码执行后将文件夹中的内容拷贝到了s中:

我们还可以用stdin&&stdout来从键盘输入数据以及从屏幕上打印数据:
int sprintf( char *buffer, const char *format [, argument] ... );
int sscanf( const char *buffer, const char *format [, argument ] ... );
- int main()
- {
-
- struct stu s1 = { "lisi","男",18,60 };
- struct stu s2 = { 0 };
- char buf[100] = { 0 };
- //把格式化的数据转换成字符串存储到buf
- sprintf(buf, "%s %s %d %lf", s1.name, s1.sex, s1.age, s1.weight);
- printf("%s\n", buf);
- //从buf中读取格式化的数据到s2中
- sscanf(buf, "%s %s %d %lf", s2.name, s2.sex, &(s2.age), &(s2.weight));
- printf("%s %s %d %lf", s2.name, s2.sex, s2.age, s2.weight);
- return 0;
- }
总结:
- scanf/printf:是针对标准输入流/标准输出流的格式化输入/输出语句。
- fscanf/fprintf:是针对所有输入流/所有输出流的格式化输入/输出语句 。
- sscanf/sprintf:sscanf是从字符串中读取格式化数据,sprintf是把格式化数据输出成(存储到)字符串。
二进制输出函数:
size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
- typedef struct stu
- {
- char name[20];
- int age;
- double weight;
- }stu;
- int main()
- {
- FILE* pf = fopen("text.txt", "wb");
- if (pf ==NULL)
- {
- printf("%s\n", strerror(errno));
- }
- stu s[2] = { {"zhangsan",18,60},{"lisi",19,65} };
- fwrite(s, sizeof(stu), 2, pf);
- fclose(pf);
- pf = NULL;
- return 0;
- }
当我们查看文件里面的内容时:

有的符号我们认识,但有的符号却很奇怪,为什么呢?
由于我们写入的时二进制的形式,所以有些符号不认识很正常,但是当我们以二进制的形式读取时就不会出现这种奇怪的符号了。
二进制输入函数:
size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
- typedef struct stu
- {
- char name[20];
- int age;
- double weight;
- }stu;
- int main()
- {
- FILE* pf = fopen("text.txt", "rb");
- if (pf == NULL)
- {
- printf("%s\n", strerror(errno));
- return 0;
- }
- stu s[2] = { 0 };
- fread(s, sizeof(stu), 2, pf);
- printf("%s %d %lf\n%s %d %lf", s[0].name, s[0].age, s[0].weight, s[1].name, s[1].age, s[1].weight);
- fclose(pf);
- pf = NULL;
- return 0;
- }
当读取信息时就会读取正常的信息:

int fseek( FILE *stream, long offset, int origin );
刚开始的时候文件中存放的是abcdef:

- int main()
- {
- FILE* pf = fopen("text.txt", "r");
- if (pf == NULL)
- {
- printf("%s\n", strerror(errno));
- return 0;
- }
- fseek(pf, 2, SEEK_CUR);
- int ch = fgetc(pf);
- printf("%c\n", ch);
- fclose(pf);
- pf = NULL;
- return 0;
- }

在这之前我们还得了解一下origin:
SEEK_CUR
Current position of file pointer
SEEK_END
End of file
SEEK_SET
Beginning of file
至于为什么打印的是c:从a开始偏移2个字符得到的就是c.此时pf指向下一个字符(也就是d):

long ftell( FILE *stream );

这个函数的用法很简单,就不多说了。
void rewind( FILE *stream );
这个函数的作用是让pf指向文件字符的开头:

好了,今天的分享就到这里了。希望老铁们能够指出文章中的错误所在,酸Q。
