目录
一、fgets和fputs
1.1.fputs
int fputs(const char *s, FILE *stream);
功能:
向流中写入一个字符串
参数:
s:字符串的首地址
stream:文件流指针
返回值:
成功返回非负数
失败返回EOF
实例
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[32] = {0};
gets(str);
FILE *fp = NULL;
fp = fopen("test.txt", "a+");
if (fp == NULL)
{
perror("open file error");
return -1;
}
fputs(str, fp);
fclose(fp);
return 0;
}
1.2.fgets
char *fgets(char *s, int size, FILE *stream);
功能:
从流中读取一行字符串
参数:
s:用于存放读取到的字符串
size:字符串的长度
stream:文件流指针
返回值:
成功返回存放字符串空间首地址
失败或者读到文件末尾返回NULL
实例
#include<stdio.h>
int main(void)
{
FILE *fp = NULL;
char strbuff[4096] = {0};
char *str = NULL;
fp = fopen("test.txt", "r");
if (fp == NULL)
{
perror("Error opening file");
return -1;
}
while(1)
{
str = fgets(strbuff, sizeof(strbuff), fp);
if (str == NULL)
{
break;
}
printf("%s", str);
}
fclose(fp);
}
1.3.与gets和puts的区别
1.fgets和gets
gets遇到'\n',会将其转变成'\0';
fgets遇到'\n',会将'保存\n'然后再在后面加上'\0';
那什么时候gets==fgets呢?
gets获取字符串时,将'\n'手动修改位'\0';
gets(filename1); == fgets(filename1, sizeof(filename1), stdin);
filename1[strlen(filename1)-1] = '\0';
2.fputs和puts
puts打印数据时会自动打印'\n';
fputs不会;
二、fscanf和fprintf
2.1. fprintf
int fprintf(FILE *stream, const char *format, ...);
功能:
向流中写入格式化字符串
2.2.fscanf
int fscanf(FILE *stream, const char *format, ...);
功能:
从流中读取格式化字符串
2.3.实例
在存入5位同学的成绩score.csv中,然后取出来求平均值,再存入avdscore.csv中
mai.c
#include <stdio.h>
#include <string.h>
#include "software.h"
int main(void)
{
char filename1[128] = {0};
char filename2[128] = {0};
int ret = 0;
printf("请输入源目录文件:");
fgets(filename1, sizeof(filename1), stdin);
filename1[strlen(filename1)-1] = '\0';
printf("请输入目的目录文件:");
fgets(filename2, sizeof(filename2), stdin);
filename2[strlen(filename2)-1] = '\0';
ret = GetStudentAvgScore(filename2, filename1);
if(ret == 0)
{
printf("success!\n");
}
else
{
printf("fail!\n");
}
return 0;
}
software.h
#ifndef _SOFTWARE_H_
#define _SOFTWARE_H_
//extern int CopyAsciiFileContent(const char *dstfile, const char *srcfile);
//extern int CopyAsciiFileContent2(const char *dstfile, const char *srcfile);
extern int GetStudentAvgScore(const char *dstfile, const char *srcfile);
#endif
software.c
/***************************************************
* 函数名: GetStudentAvgScore
* 功 能:
* 取学生成绩并计算平均值放到另一个文件中
* 参 数:
* dstfile: 目标文件的文件路径
* srcfile: 源文件的文件路径
* 返回值:
* 成功:返回0
* 失败:返回1
*
* 注 意:
* 获取的是格式化数据
*****************************************************/
int GetStudentAvgScore(const char *dstfile, const char *srcfile)
{
int num1 = 0;
int num2 = 0;
int num3 = 0;
int ret = 0;
double avgs = 0;
FILE *fp1 = NULL;
fp1 = fopen(srcfile, "r");
if (fp1 == NULL)
{
perror("open file failed");
goto err1;
}
FILE *fp2 = NULL;
fp2 = fopen(dstfile, "w");
if (fp2 == NULL)
{
perror("open file failed");
goto err2;
}
while(1)
{
ret = fscanf(fp1, "%d,%d,%d", &num1, &num2, &num3);
if(ret == EOF)
{
break;
}
avgs = (num1 + num2 + num3) / 3.0;
fprintf(fp2, "%.3f\n", avgs);
}
fclose(fp1);
fclose(fp2);
return 0;
err2:
fclose(fp1);
err1:
return -1;
}
源文件
98,97,96
93,91,83
64,74,98
89,66,51
47,63,39
目标文件
97.000
89.000
78.667
68.667
49.667
三、fread和fwrite
3.1.fwrite
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
向流中写入nmemb个对象,每个对象size个字节,在ptr指向的空间中存放
参数:
ptr:写入数据空间的首地址
size:每个对象的大小
nmemb:写入对象的个数
stream:文件流指针
返回值:
成功返回实际写入对象的个数
失败返回0
实例
#include <stdio.h>
typedef struct stduent
{
char name[128];
char sex;
int age;
int score;
}stu_t;
int main(void)
{
stu_t s[3] = {
{"张三", 'm', 20, 98},
{"李四", 'm', 20, 99},
{"王五", 'm', 20, 97},
};
size_t ret = 0;
FILE *fp = NULL;
fp = fopen("a.txt","w");
if(fp == NULL)
{
perror("open failed");
return -1;
}
ret = fwrite(s, sizeof(stu_t), 3, fp);
printf("ret = %ld\n", ret);
fclose(fp);
return 0;
}
3.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[128];
char sex;
int age;
int score;
}stu_t;
int main(void)
{
stu_t s[4] = {0};
FILE *fp = NULL;
size_t ret = 0;
int i =0;
fp = fopen("a.txt", "r");
if(fp == NULL)
{
perror("open failed");
return -1;
}
ret = fread(s, sizeof(stu_t), 4, fp);
for(i = 0; i < ret; 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);
}
fclose(fp);
return 0;
}
四、总结
标准IO中,有四对读取和写入的函数接口,fgtec和fputc,读取一个字符;fgtes和fputs,按行读写文件流;fscanf和fprintf按格式化数据读写文件流;fread和fwrite,可以读写二进制文件流。其中呢,fgtes和gtes有着一个很明显的区别,就是gets会将读取'\n'其转化为'\0';fgtes读取'\n',在他后面再接上'\0'。puts在打印时会自动在末尾换行;fputs在打印时在末尾需要手动打印'\n';