Linux 文件操作-标准IO函数3- fread读取、fwrite写入、 fprintf向文件写入格式化数据、fscanf逐行读取格式化数据的验证
目录
1. fread 从文件中读取数据
1.1 读取次数 × 每次读取字节数 < 原内容字节数
1.2 读取次数 × 每次读取字节数 > 原内容字节数
2.fwrite 向文件中写入数据
2.1写入字符串验证
2.2写入结构体验证
3. fprintf 将数据写入到指定文件
4. fscanf 从文件中逐行读取内容,并将其存储在结构中
4.1 读取整形、浮点型、字符程序:
4.2 读取结构体程序:
4.2.1读取 空格 间隔数据
4.2.2读取 空格-空格 间隔数据
5.fprintf 和 fscanf 联合使用
1. fread 从文件中读取数据
函数原型:
/* 功能:从文件中读取数据
参数:
ptr:保存读取的数据
size:每次读取的字节数
nmemb:一共读取的次数
stream:文件指针
返回值:
成功:实际读取的次数(对象数、块数)
失败:0
如果文件内容读取完毕,返回0 */
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
1.1 读取次数 × 每次读取字节数 < 原内容字节数
程序:file.txt 共32个字节,程序读取3次,每次6个字节,共18个字节。
#include <stdio.h>
int test1()
{
FILE *fp = NULL;
//只读打开 file.txt
fp = fopen("./file.txt", "r");
if(fp == NULL)
{
printf("fail to fopen\n");
return -1;
}
//使用fread函数读取文件内容
int num;
char buf[64] = {0};
//从fp中读取3次数据,每次读取6个字节,保存到buf
num = fread(buf, 6, 3, fp);
printf("buf = %s\n", buf);
printf("num = %d\n", num);
if(num == 0)
{
printf(" fail to fread \n", num);
}
fclose(fp);
return 0;
}
int main(int argc, char *argv[])
{
test1();
return 0;
}
运行结果:
1.2 读取次数 × 每次读取字节数 > 原内容字节数
例: fread(buf, size, num, fp); //读取num次,每次size个字节大小。
若:如果读到 n*size 个字节,返回值为 n
.....
如果读到了大于等于2*size 个字节, 小于3*size个字节, 返回值为 2
读到的字节数,大于等于size 个字节 ,小于2*size个字节, 返回值为 1
不到size 个字节,返回值为 0
int num = fread(str,10,3,fp);
读取的字节数为 ,每次读取10个字节,读3次, 返回值为num。
如果读到30个字节,返回值num为3
如果读到了大于等于20个字节,小于30个字节, 返回值为2
读到的字节数,大于等于10个字节,小于20个字节 返回值为1
不到10个字节,返回值为0
程序:
#include <stdio.h>
int test1()
{
FILE *fp = NULL;
//只读打开 file.txt
fp = fopen("./file.txt", "r");
if(fp == NULL)
{
printf("fail to fopen\n");
return -1;
}
//使用fread函数读取文件内容
int num;
char buf[64] = {0};
//从fp中读取3次数据,每次读取6个字节,保存到buf
num = fread(buf, 30, 3, fp);
printf("buf = %s\n", buf);
printf("num = %d\n", num);
if(num == 0)
{
printf(" fail to fread \n", num);
}
fclose(fp);
return 0;
}
int main(int argc, char *argv[])
{
test1();
return 0;
}
运行结果:修改程序每次读取字节数
(1)num = fread(buf, 30, 3, fp);
(2)num = fread(buf, 15, 3, fp);
(3)num = fread(buf, 35, 3, fp);
2.fwrite 向文件中写入数据
函数原型:
/*功能:向文件中写入数据
参数:
ptr:要写入的数据
size:一次写入的字节数
nmemb:一共写入的次数
stream:文件指针
返回值:
成功:实际写入的次数
失败:0 */
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
2.1写入字符串验证
程序:
#include <stdio.h>
#include <string.h>
int test1()
{
FILE *fp = NULL;
//读写打开 file.txt,不存在创建,存在清0
fp = fopen("./file.txt", "w+");
if(fp == NULL)
{
printf("fail to fopen\n");
return -1;
}
int num;
char buf[] = {"hello world"};
//向fp中写入3次数据,每次写入strlen(buf)个字节,
num = fwrite(buf, strlen(buf), 3, fp);
printf("strlen(buf) = %d\n", strlen(buf));
printf("fwrite num = %d\n", num);
printf("fwrite size = %d\n", num*strlen(buf));//向文件写入字节大小
if(num == 0)
{
printf(" fail to fwrite \n", num);
}
//将文件的偏移量设置为文件的起始位置
rewind(fp);
//使用fread函数读取文件内容
char buf1[128] = {0};
//从fp中读取3次数据,每次读取strlen(buf)个字节,保存到buf1
num = fread(buf1, strlen(buf), 3, fp);
printf("fread num = %d\n", num);
printf("buf1 = %s\n", buf1);
printf("strlen(buf1) = %d\n", strlen(buf1));
if(num == 0)
{
printf(" fail to fread \n", num);
}
fclose(fp);
return 0;
}
int main(int argc, char *argv[])
{
test1();
return 0;
}
运行结果:对file.txt写入3次hello world ,每次写入11个字节
2.2写入结构体验证
程序:
#include <stdio.h>
#include <string.h>
typedef struct{
int i1;
int i2;
char c1;
char c2;
}DATA;
int test2()
{
FILE *fp = NULL;
fp = fopen("./file1.txt", "w+");
if(fp == NULL)
{
printf("fail to fopen\n");
return -1;
}
//使用fwrite向文件写入一个结构体
DATA data[3] = {1, 2, 'a', 'b', 3, 4, 'c', 'd', 5, 6, 'e', 'f',};
//向fp写入3次数据,每次sizeof(DATA)个字节
int num = fwrite(data, sizeof(DATA), 3, fp);
printf("fwrite num = %d\n", num);
//将文件的偏移量设置为文件的起始位置,不设为起始,读取位置将从写入最后一个字节之后开始。
rewind(fp);
DATA read_data[3];
//从fp读取写入数据,每次sizeof(DATA)个字节,读取3次数据
int num1 = fread(read_data, sizeof(DATA), 3, fp);
printf("fread num = %d\n", num1);
int j;
for(j = 0; j < 3; j++) //循环读取read_data数据
{
printf("%d - %d - %c - %c\n", read_data[j].i1, read_data[j].i2, read_data[j].c1, read_data[j].c2);
}
fclose(fp);
return 0;
}
int main(int argc, char *argv[])
{
test2();
return 0;
}
运行结果:
3. fprintf 将数据写入到指定文件
函数原型:
/* fprintf 和printf函数类似:
printf是将数据输出到屏幕上(标准输出),
fprintf函数是将数据输出到文件指针所指定的文件中。 */
/* 参数:
stream:文件指针,指定输出目标(如文件、stdout、stderr)。
format:格式化字符串,定义输出格式(如 %d, %s, %f)。
...:可变参数列表,对应 format 中的格式说明符。
返回值:成功时返回写入的字符数,失败时返回负值。 */
int fprintf(FILE *stream, const char *format, ...);
程序:
#include <stdio.h>
#include <string.h>
int test1()
{
char ch='a';
int num=10;
char str[20]="hello world";
float score = 68.9;
FILE *fp = NULL;
//读写打开 file.txt
fp = fopen("./file.txt", "w+");
if(fp == NULL)
{
printf("fail to fopen\n");
return -1;
}
//使用fprintf向文件写入字符串
int num1 = fprintf(fp,"%c %d %s %f\n",ch,num,str,score);
printf("fprintf num = %d\n", num1);
if(num1 < 0)
{
printf(" fail to fprintf \n");
return -1;
}
fclose(fp);
return 0;
}
int main(int argc, char *argv[])
{
test1();
return 0;
}
运行结果:
4. fscanf 从文件中逐行读取内容,并将其存储在结构中
函数原型:
/* fscanf和scanf 函数类似:
scanf是从键盘(标准输入)获取输入,
fscanf是从文件指针所标示的文件中获取输入。 */
/* 参数:
stream:文件指针(如 FILE *fp 或 stdin)。
format:格式字符串,定义输入数据的格式(如 %d, %s, %f)。
...:可变参数列表,需为变量地址(如 &num, name 数组名)
返回值:
成功时,返回输入数据格式数量(%d %s 等成功读取的个数)。
失败或 文件结尾返回 EOF(即 -1) */
int fscanf(FILE *stream, const char *format, ...)
4.1 读取整形、浮点型、字符程序:
#include <stdio.h>
#include <string.h>
int test1()
{
char ch;
int num;
char str[32] = "";
float score ;
FILE *fp = NULL;
//追加读写打开 file.txt
fp = fopen("./file.txt", "r");
if(fp == NULL)
{
printf("fail to fopen\n");
return -1;
}
//将文件的偏移量设置为文件的起始位置,不设为起始,读取位置将从写入最后一个字节之后开始。
//rewind(fp);
//从指定文件读取数据
int num1 = fscanf(fp,"%c %d %s %f\n", &ch, &num, &str, &score);
printf("ch= %c num= %d str= %s score= %f\n", ch, num, str, score);
printf("fprintf num1 = %d\n", num1);
if(num1 == EOF)
{
printf(" fprintf fail or end \n");
return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
test1();
fclose(fp);
return 0;
}
运行结果:
file.txt原有内容:
4.2 读取结构体程序:
4.2.1读取 空格 间隔数据
程序:
#include <stdio.h>
#include <string.h>
typedef struct
{
char name[32];
int age;
int score;
}DATA;
int test2()//循环读取文件内容
{
FILE *fp = NULL;
//只读打开 file.txt
fp = fopen("./file1.txt", "r");
if(fp == NULL)
{
printf("fail to fopen\n");
return -1;
}
DATA dt;
//从指定文件循环读取一行数据
while(fscanf(fp, "%s %d %d\n", dt.name, &dt.age, &dt.score) == 3) //char name[32];
{
printf("name= %s age= %d score= %d\n", dt.name, dt.age, dt.score );
}
fclose(fp);
return 0;
}
int main(int argc, char *argv[])
{
test2();
return 0;
}
运行结果:
注意fscanf第二个参数要与文件数据格式保持一致。
fscanf(fp, "%s %d %d", dt.name, &dt.age, &dt.score);
4.2.2读取 空格-空格 间隔数据
程序:
#include <stdio.h>
#include <string.h>
typedef struct
{
char name[32];
int age;
int score;
}DATA;
int test2()//循环读取文件内容
{
FILE *fp = NULL;
//只读打开 file.txt
fp = fopen("./file1.txt", "r");
if(fp == NULL)
{
printf("fail to fopen\n");
return -1;
}
DATA dt;
//fprintf 和 fscanf 联合使用,fprintf写入文本时加入\n,在fscanf读取时也要加\n。
//单独使用fscanf读取多行数据时,可不加\n
//从指定文件循环读取一行数据
while(fscanf(fp, "%s - %d - %d", dt.name, &dt.age, &dt.score) == 3)
//while(fscanf(fp, "%s - %d - %d\n", dt.name, &dt.age, &dt.score) == 3)
{
printf("name= %s age= %d score= %d\n", dt.name, dt.age, dt.score );
}
fclose(fp);
return 0;
}
int main(int argc, char *argv[])
{
test2();
return 0;
}
运行结果:注意fscanf第二个参数要与文件数据格式保持一致。
fscanf(fp, "%s - %d - %d", dt.name, &dt.age, &dt.score);
5.fprintf 和 fscanf 联合使用
程序:
#include <stdio.h>
#include <string.h>
int test4()//
{
FILE *fp = NULL;
//读写打开 file.txt
fp = fopen("./file.txt", "w+");
if(fp == NULL)
{
printf("fail to fopen\n");
return -1;
}
int num = 0;
char ch1 = 'a', ch11;
int i1 = 1, i11;
char ch2 = 'e', ch22;
int i2 = 10, i22;
int j = 0;
for(j = 0;j < 3;j++)
{
//使用fprintf向文件写入字符串
num = fprintf(fp,"%c %d %c %d\n",ch1 + j, i1 + j, ch2 + j, i2 + j);
if(num < 0)
{
printf("fail to fprintf\n");
}
}
//将文件的偏移量设置为文件的起始位置,不设为起始,读取位置将从写入最后一个字节之后开始。
rewind(fp);
//fprintf 和 fscanf 联合使用,fprintf写入文本时加入\n,在fscanf读取时也要加\n。
//单独使用fscanf读取多行数据时,可不加\n
//从指定文件循环读取一行数据
//while(fscanf(fp, "%c %d %c %d\n",&ch11 , &i11 , &ch22 , &i22) == 4)
{
printf("read:%c %d %c %d\n", ch11 , i11 , ch22 , i22 );
}
fclose(fp);
return 0;
}
int main(int argc, char *argv[])
{
test4();
return 0;
}
运行结果:
注意:(1)写入文件后,将偏移量移至文件开头。 // rewind(fp);
(2)程序写入了 \n;
fprintf(fp,"%c %d %c %d\n",ch1 + j, i1 + j, ch2 + j, i2 + j);
读取时也要加:
while(fscanf(fp, "%c %d %c %d\n",&ch11 , &i11 , &ch22 , &i22) == 4)
(3)//fprintf 和 fscanf 联合使用,fprintf写入文本时加入\n,在fscanf读取时也要加\n。
//单独使用fscanf读取多行数据时,可不加\n