前言
本篇接上一篇文件操作(上篇)的内容
文件的顺序读写
在上一篇已经介绍了前面四个了,接下来介绍后面四个
fscanf和fprintf
上面的四个都是针对字符的输入输出,但是实际文件会有不同的数据类型,这时就需要用到格式化输入输出函数了
其实就是比scanf和printf多了个文件输入输出流,返回值规则都一样的
- fprintf
int fprintf ( FILE * stream, const char * format, ... );
- 写文件
struct S
{
char name[20];
int age;
float score;
};
int main()
{
struct S s = { "lisi", 18, 88.0f };
//1. 打开文件
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//2. 写文件
fprintf(pf,"%s %d %.1f", s.name, s.age, s.score);
//printf("%s %d %f", name, age, score);
//3. 关闭文件
fclose(pf);
pf = NULL;
return 0;
}
- fscanf
int fscanf ( FILE * stream, const char * format, ... );
- 读文件并打印在控制台上
int main()
{
struct S s = {0};
//1. 打开文件
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//2. 读文件
//scanf("%s %d %f", s.name, &(s.age), &(s.score));
//从文件中读取信息,存放到s的各个成员中
fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));
//打印在屏幕上
//printf("%s %d %.1fn", s.name, s.age, s.score);
fprintf(stdout, "%s %d %.1fn", s.name, s.age, s.score);
//3. 关闭文件
fclose(pf);
pf = NULL;
return 0;
}
- 参数都是比scanf和printf多了个文件指针而已
补充:sscanf和sprintf
- printf是把数据输出到控制台上(标准输出流)
- fprintf是把数据输出到文件中(文件输出流)
- sprintf是把数据输出到字符数组中
- scanf是从键盘上读取数据(标准输入流)
- fscanf是从文件中读取数据(文件输入流)
- sscnaf是从字符数组中读取数据
struct S
{
char name[20];
int age;
float score;
};
int main()
{
char arr[100] = { 0 };
struct S s = { "wangwu", 23, 66.6f };
//临时变量
struct S tmp = { 0 };
//将s中的各个数据转换成字符串,存放在arr中
sprintf(arr, "%s %d %f", s.name, s.age, s.score);
//printf("%sn", arr);
//从字符串arr中提取格式化的数据,存放在tmp中
sscanf(arr, "%s %d %f", tmp.name, &(tmp.age), &(tmp.score));
printf("%s %d %fn", tmp.name, tmp.age, tmp.score);
return 0;
}
fread和fwrite
只适用于文件输入输出流
- fwrite
- 以二进制形式写入文件使用wb
- 把ptr指向空间的count个大小为size字节的数据写入文件中
- 返回成功写入的元素个数
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
- 写文件
struct S
{
char name[20];
int age;
float score;
};
int main()
{
struct S s = { "cuihua", 25, 88.8f };
//以二进制的形式写到文件中
//1. 打开文件
FILE* pf = fopen("test.txt", "wb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//2.写文件
fwrite(&s, sizeof(struct S), 1, pf);
//3.关闭文件
fclose(pf);
pf = NULL;
return 0;
}
- fread
- 以二进制形式读取文件使用rb
- 从文件里面读取count个大小为size字节的数据存放在ptr指向的空间中
- 返回成功读取的元素个数
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
- 读文件
int main()
{
struct S s = {0};
//1. 打开文件
FILE* pf = fopen("test.txt", "rb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//2.读文件
fread(&s, sizeof(struct S), 1, pf);
printf("%s %d %fn", s.name, s.age, s.score);
//3.关闭文件
fclose(pf);
pf = NULL;
return 0;
}
文件的随机读写
fseek
根据⽂件指针的位置和偏移量来定位⽂件指针(⽂件内容的光标)
- offset:偏移量(左偏移是负,右偏移是正),单位是字节
- origin有三个选项:
- SEEK_SET:文件开头
- SEEK_CUR:当前光标位置
- SEEK_END:文件末尾
int fseek ( FILE * stream, long int offset, int origin );
例子:
代码语言:javascript复制/* fseek example */
#include <stdio.h>
int main ()
{
FILE * pFile;
pFile = fopen ( "example.txt" , "wb" );
fputs ( "This is an apple." , pFile );
fseek ( pFile , 9 , SEEK_SET );
fputs ( " sam" , pFile );
fclose ( pFile );
return 0;
}
ftell
返回⽂件指针相对于起始位置的偏移量(单位仍是字节)
代码语言:javascript复制long int ftell ( FILE * stream );
例子:
代码语言:javascript复制/* ftell example : getting size of a file */
#include <stdio.h>
int main ()
{
FILE * pFile;
long size;
pFile = fopen ("myfile.txt","rb");
if (pFile==NULL)
perror ("Error opening file");
else
{
fseek (pFile, 0, SEEK_END); // non-portable
size=ftell (pFile);
fclose (pFile);
printf ("Size of myfile.txt: %ld bytes.n",size);
}
return 0;
}
rewind
让⽂件指针的位置回到⽂件的起始位置
代码语言:javascript复制void rewind ( FILE * stream );
例子:
代码语言:javascript复制/* rewind example */
#include <stdio.h>
int main ()
{
int n;
FILE * pFile;
char buffer [27];
pFile = fopen ("myfile.txt","w ");
for ( n='A' ; n<='Z' ; n )
fputc ( n, pFile);
rewind (pFile);
fread (buffer,1,26,pFile);
fclose (pFile);
buffer[26]='