1.fputs和fgets
1.fputs
int fputs(const char *s, FILE *stream);
功能:
向流中写入一个字符串
参数:
s:字符串的首地址
stream:文件流指针
返回值:
成功返回非负数
失败返回EOF
2.fgets
char *fgets(char *s, int size, FILE *stream);
功能:
从流中读取一行字符串
参数:
s:用于存放读取到的字符串
size:字符串的长度
stream:文件流指针
返回值:
成功返回存放字符串空间首地址
失败或者读到文件末尾返回NULL
练习:利用fgets和fputs实现将一个文件中的内容拷贝到另一个文件中
#include "software.h"
#include <stdio.h>
/***************************************************
* 函数名:CopyAsciiFileContent
* 功 能:
* 将srcfile中的文件内容拷贝到dstfile文件中
* 参 数:
* dstfile:目的文件的文件路径
* srcfile:源文件的文件路径
* 返回值:
* 成功返回0
* 失败返回-1
* 注意事项:
* 1.该函数只能拷贝ASCII普通文件内容
**************************************************/
int CopyAsciiFileContent(const char *dstfile, const char *srcfile)
{
FILE *fsrc = NULL;
FILE *fdst = NULL;
int temp = 0;
fsrc = fopen(srcfile, "r");
if (NULL == fsrc)
{
goto err2;
}
fdst = fopen(dstfile, "w");
if (NULL == fdst)
{
goto err1;
}
while (1)
{
temp = fgetc(fsrc);
if (EOF == temp)
{
break;
}
fputc(temp, fdst);
}
fclose(fsrc);
fclose(fdst);
return 0;
err1:
fclose(fsrc);
err2:
return -1;
}
/***************************************************
* 函数名:CopyAsciiFileContent2
* 功 能:
* 将srcfile中的文件内容拷贝到dstfile文件中
* 参 数:
* dstfile:目的文件的文件路径
* srcfile:源文件的文件路径
* 返回值:
* 成功返回0
* 失败返回-1
* 注意事项:
* 1.该函数只能拷贝ASCII普通文件内容
**************************************************/
int CopyAsciiFileContent2(const char *dstfile, const char *srcfile)
{
FILE *fsrc = NULL;
FILE *fdst = NULL;
char tmpbuff[4096] = {0};
char *pret = NULL;
fsrc = fopen(srcfile, "r");
if (NULL == fsrc)
{
goto err1;
}
fdst = fopen(dstfile, "w");
if (NULL == fdst)
{
goto err2;
}
while (1)
{
pret = fgets(tmpbuff, sizeof(tmpbuff), fsrc);
if (NULL == pret)
{
break;
}
fputs(tmpbuff, fdst);
}
fclose(fsrc);
fclose(fdst);
return 0;
err2:
fclose(fsrc);
err1:
return -1;
}
puts(tmpbuff);
fputs(tmpbuff, stdout);
puts会多打印一个\n字符
gets(tmpbuff);
fgets(tmpbuff, sizeof(tmpbuff), stdin);
gets会去掉用户输入\n字符
fgets不会去掉用户输入的\n字符
2.fprintf和fscanf
int fprintf(FILE *stream, const char *format, ...);
功能:
向流中写入格式化字符串
fprintf(stdout, ...);
printf(...);
int fscanf(FILE *stream, const char *format, ...);
功能:
从流中读取格式化字符串
fscanf(stdin, ...);
scanf(...);
练习:
将score.csv中每个学生的成绩获得平均值逐行写入到avg.csv中
#include <stdio.h>
int main(void)
{
FILE *fsrc = NULL;
FILE *fdst = NULL;
int score1 = 0;
int score2 = 0;
int score3 = 0;
double avgscore = 0;
int ret = 0;
fsrc = fopen("score.csv", "r");
if (NULL == fsrc)
{
perror("fail to fopen");
return -1;
}
fdst = fopen("avg.csv", "w");
if (NULL == fdst)
{
perror("fail to fopen");
fclose(fsrc);
return -1;
}
while (1)
{
ret = fscanf(fsrc, "%d,%d,%d", &score1, &score2, &score3);
if (EOF == ret)
{
break;
}
avgscore = (score1 + score2 + score3) / 3.0;
fprintf(fdst, "%.2lf\n", avgscore);
}
fclose(fsrc);
fclose(fdst);
return 0;
}
3.fread和fwrite
2024
ASCII码文件: '2' '0' '2' '4' 代码、文本文件
00110010 00110000 00110010 00110100
二进制文件: 2024 视频、图片、压缩包等
0000 0000 0000 0000 0000 0111 1110 1000
ASCII码文件是一种特殊的二进制文件
1.fwrite
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
向流中写入nmemb个对象,每个对象size个字节,在ptr指向的空间中存放
参数:
ptr:写入数据空间的首地址
size:每个对象的大小
nmemb:写入对象的个数
stream:文件流指针
返回值:
成功返回实际写入对象的个数
失败返回0
2.fread
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
从流中读取nmemb个对象,每个对象size个字节,在ptr指向的空间中存放
参数:
ptr:存放数据空间的首地址
size:每个对象的大小
nmemb:写入对象的个数
stream:文件流指针
返回值:
成功返回实际读取对象的个数
失败或者读到文件末尾返回0
#include <stdio.h>
typedef struct student
{
char name[32];
char sex;
int age;
int score;
}stu_t;
int main(void)
{
FILE *fp = NULL;
stu_t temp;
stu_t s[4];
int i = 0;
size_t nret = 0;
fp = fopen("file.txt", "r");
if (NULL == fp)
{
perror("fail to fopen");
return -1;
}
nret = fread(s, sizeof(stu_t), 4, fp);
for (i = 0; i < nret; i++)
{
printf("姓名:%s\n", s[i].name);
printf("性别:%c\n", s[i].sex);
printf("年龄:%d\n", s[i].age);
printf("成绩:%d\n", s[i].score);
}
#if 0
while (1)
{
nret = fread(&temp, sizeof(stu_t), 1, fp);
if (0 == nret)
{
break;
}
printf("姓名:%s\n", temp.name);
printf("性别:%c\n", temp.sex);
printf("年龄:%d\n", temp.age);
printf("成绩:%d\n", temp.score);
}
#endif
fclose(fp);
return 0;
}