文件IO(二)
标准IO
标准IO:
1.标准IO由ANSI C标准定义, 库函数提供的
2.跨平台性,移植性较好
3.有缓冲区的操作,标准IO的效率比文件IO的效率高
4.一般以文件流指针作为操作依据
缓冲类型
全缓冲
缓冲区满了,或者强制刷新缓冲区
行缓冲
缓冲区满了,碰到换行符或者强制刷新缓冲区
不缓冲
缓冲区的数据及时的出来了
打开文件
fopen
#include <stdio.h>
FILE *fopen(const char *pathname, const char *mode);
函数功能:以mode表示的形式打开pathname表示的文件的路径
函数参数:pathname 表示被打开的文件的路径
mode 打开文件的方式
r 以只读的形式打开文件,光标置于开头
r+ 以可读可写的形式打开文件,光标置于开头
w 以只写的形式打开文件,文件存在清空打开,文件不存在新建,光标置于开头
w+ 以可读可写的形式打开文件,文件存在清空打开,文件不存在新建,光标置于开头
a 以追加的形式打开文件(写在末尾),文件不存在则新建,光标置于文件末尾
a+ 以可读并追加的形式打开文件,文件不存在则新建,光标置于文件末尾
函数返回值:指针,成功返回打开的文件的流指针,失败返回NULL,并更新errno
操作文件
按字符读写(fgetc fputc)
#include <stdio.h>
int fgetc(FILE *stream);
函数功能:读stream指示的文件,成功返回读到的数据(无符号的char强转成的int),失败或者读完了返回EOF(-1)
int fputc(int c, FILE *stream);
函数功能:将c转换成无符号的char数据,写入到文件stream里
实现cat命令
实现cp命令
按行读写(fgets fputs)
#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
函数功能:从stream指示的流中读取size-1个字符给s指示的空间
最后一个字符给\0预留
函数返回值:成功返回s的地址,失败返回NULL
int fputs(const char *s, FILE *stream);
函数功能:王stream指示的文件流中写入s指示的数据,写到\0为止
函数返回值:成功返回成功写入的大小,失败返回-1
实现:统计一个文件中有多少行
按块(对象)读写(fread fwrite)
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
函数功能:从stream指示的文件中读nmemb个数据,每一个数据有size个大小,到ptr指示的空间中
函数返回值:成功返回成功读到的个数,失败返回0
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
函数功能:往stream里面写nmemb个数据,每一个数据有size个大小,数据从ptr来的
函数返回值:成功返回成功写入的个数,失败返回0
案例,通过fwrite保存数据,另外一个程序通过fread读取数据
myhead.h
#ifndef _MYHEAD_H_
#define _MYHEAD_H_
#include <stdio.h>
typedef struct student
{
char name[20];
char id[20];
int age;
}Stu;
#endif
mywri.c
#include "myhead.h"
int main(int argc, const char *argv[])
{
FILE *pw = NULL;
//打开文件
pw = fopen("msg.txt", "w");
if(!pw)
{
perror("open");
return -1;
}
//操作文件
//1.给数据赋值
Stu stu1 = {"xiaoming", "yan24020202", 24};
//写数据,内存stu1 --> 文件pw
//fwrite(ptr, size, nmemb, stream);
fwrite(&stu1, sizeof(Stu), 1, pw);
//关闭文件
fclose(pw);
return 0;
}
myred.c
#include "myhead.h"
#include <stdlib.h>
#include <string.h>
int main(int argc, const char *argv[])
{
FILE *pr = NULL;
//申请一片空间
Stu *ptr = (Stu *)malloc(sizeof(Stu));
//清空
memset(ptr, 0, sizeof(Stu));
//打开文件
pr = fopen("msg.txt", "r");
if(!pr)
{
perror("open");
return -1;
}
//操作文件
//将数据,从pr中读到内存上来使用
//fread(ptr, size, nmemb, stream);
fread(ptr, sizeof(Stu), 1, pr);
printf("name : %s \n", ptr->name);
printf("id : %s \n", ptr->id);
printf("age : %d \n", ptr->age);
//关闭文件
fclose(pr);
return 0;
}
按格式化读写(fscanf fprintf)
#include <stdio.h>
int fprintf(FILE *stream, const char *format, …);
函数功能:往指定的文件中输出信息,用法和printf一样
int fscanf(FILE *stream, const char *format, …);
函数功能:从指定的文件中读取数据,用法和scanf一样
关闭文件(fclose)
#include <stdio.h>
int fclose(FILE *stream);
函数功能:关闭stream指示的流
相关的函数
强制刷新缓冲区(fflush)
#include <stdio.h>
int fflush(FILE *stream);
判断文件是否到末尾(feof)
#include <stdio.h>
int feof(FILE *stream);
获取本地时间(time)
#include <time.h>
time_t time(time_t *tloc);
函数功能:获取本机时间(以秒数存储,从1970年1月1日0:0:0开始到现在)
返回值:获得的秒数,如果形参非空,返回值也可以通过传址调用的形式返回
#include <time.h>
struct tm *localtime(const time_t timep);
函数功能:将timep(时间戳变量)转成认识的结果,将结果封装成struct tm类型的结构体
返回值:返回struct tm类型的结构体指针
struct tm {
int tm_sec; / Seconds (0-60) /
int tm_min; / Minutes (0-59) /
int tm_hour; / Hours (0-23) /
int tm_mday; / Day of the month (1-31) /
int tm_mon; / Month (0-11) /
int tm_year; / Year - 1900 /
int tm_wday; / Day of the week (0-6, Sunday = 0) /
int tm_yday; / Day in the year (0-365, 1 Jan = 0) /
int tm_isdst; / Daylight saving time */
};
光标跳转(fseek、ftell)
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);
函数功能:跳转光标
函数参数1:待跳转光标的文件
函数参数2:光标的偏移量
函数参数3:从哪里开始偏移
SEEK_SET, 从文件开头
SEEK_CUR, 从当前位置
SEEK_END, 从文件末尾
返回值:成功返回0,失败返回-1并更新errno
long ftell(FILE *stream);
函数功能:返回stream文件的光标的位置
案例:获取一个文件有多大
1.打开文件
2.光标跳转到末尾 (SEEK_END 0 )
3.返回当前光标的位置
案例:制作一个空洞文件