【文件I/O】标准IO:库函数
创始人
2024-03-08 15:37:18
0

标准IO:库函数

  • 一、基本概念
    • 1.文件类型
    • 2.标准I/O介绍
    • 3.流的概念
    • 4.文本流和二进制流
    • 5.流的缓冲类型
    • 6.标准I/O流(stdin、stdout、stderr)
  • 二、标准I/O函数
    • 1.fopen、fclose、errrno、strerror、perror(打开、关闭文件,输出错误码信息)
    • 2.fgetc、fputc、getchar、putchar(读写一个字符)
    • 3.fgets、fputs、gets、puts(读写一行)
    • 4.fread、fwrite(读写若干个对象)
    • 5.feof、ferror(判断文件是否结束或出错)
    • 6.sprintf、snprintf、fprintf(格式化输出到内存、文件)
    • 7.time、localtime(获取系统时间,将系统时间转为本地时间)
    • 8.fflush(刷新缓冲区)
    • 9.fseek、rewind、ftell(定位文件指针)
    • 10.freopen(重定向输入输出流)
  • 三、示例代码
    • 1.fgetc(统计文本文件字符数)
    • 2.fputc(将a~z写入文件)
    • 3.fgets(标准输入流写入buff)
    • 4.fputs(将内存数据输出到标准输出流)
    • 5.fread、fwrite(二进制文件读写)
    • 6.fflush(刷新流,刷新缓冲区)
    • 7.ftell、fseek、rewind(定位流指针)
    • 8.fprintf、sprintf(格式化输出数据到文件、内存,常用sprintf)
    • 9.fscanf、sscanf(将文件、内存数据格式化输入,可用作解析字符串)
  • 四、案例源码
    • 1.复制文件1
    • 2.统计文本文件行数
    • 3.复制文件2
    • 4.获取文件长度
    • 5.按指定格式打印时间

一、基本概念

1.文件类型

概念:一组相关数据的有序集合
文件类型:

  1. 常规文件 r
  2. 目录文件 d
  3. 字符设备文件 c
  4. 块设备文件 b
  5. 管道文件 p
  6. 套接字文件 s
  7. 符号链接文件 l

2.标准I/O介绍

标志I/O由ANSI C标准定义,主流操作系统上都实现了C库
标准I/O通过缓冲机制减少系统调用,实现更高的效率

3.流的概念

FILE:
标准I/O用一个结构体类型来存放打开的文件的相关信息
标准I/O的所有操作都是围绕FILEl来进行

流(stream):
FILE又被称为流(stream)
文本流/二进制流

4.文本流和二进制流

windows
二进制流:换行符 <—> ‘\n’
文本流:换行符 <—> ‘\r’‘\n’

Liniux
换行符 <—> ‘\n’

5.流的缓冲类型

全缓冲
当流的缓冲区无数据或无空间时才执行实际I/O操作

行缓冲
当输入和输出中遇到换行符(‘\n’)时,进行I/O操作
当流和一个终端关联时,典型的行缓冲

无缓冲
数据直接写入文件,流不进行缓冲

6.标准I/O流(stdin、stdout、stderr)

标准I/O预定义3个流,程序运行时自动打开

标准输入流0STDIN_FILENOstdin
标准输出流1STDOUT_FILENOstdout
标准错误流2STDERR_FILENOstderr

二、标准I/O函数

1.fopen、fclose、errrno、strerror、perror(打开、关闭文件,输出错误码信息)

FILE *fopen(const char *pathname, const char *mode);
功能:打开文件(标准IO)
参数:@pathname:想要打开文件的路径及名字 "./hello.txt" "/home/linux/1.c"@mode:打开文件的方式 "a" "a+" "w" "w+" "r" "r+"r      以只读的方式打开文件,将光标定位到文件的开头r+     以读写的方式打开文件,将光标定位到文件的开头w      以只写方式打开文件,如果文件存在就清空,如果文件不存在就创建,将光标定位到开头w+     以读写方式打开文件,如果文件存在就清空,如果文件不存在就创建,将光标定位到开头a      以追加的方式打开文件,如果文件不存在就创建,如果文件存在不会清空,将光标定位到结尾a+     以读和追加的方式打开文件,如果文件不存在就创建,读光标在开头,写光标在结尾(光标就一个)
返回值:成功返回文件指针,失败返回NULL,置位错误码errno
int fclose(FILE *stream);
功能:关闭文件
参数:@stream:文件指针返回值:成功返回0,失败返回EOF(-1),置位错误码  //#define EOF (-1)
#include 
extern int errno;
errno 存放错误码
#include 
char *strerror(int errnum);
功能:将错误码转换为错误信息
参数:@errnum:错误码
返回值:错误信息的字符串
void perror(const char *s);
功能:打印错误信息
参数:@s:用户的附加信息
返回值:无

2.fgetc、fputc、getchar、putchar(读写一个字符)

int fgetc(FILE *stream);
功能:从文件中读取一个字符(光标自动向后移动)
参数:@stream:文件指针
返回值:成功返回读取到的字符的ASCII,读取到结尾或者遇到错误就返回EOF
int fputc(int c, FILE *stream);
功能:向文件中写入一个字符(光标自动向后移动)
参数:@c:字符的ascii的值 ‘c’ 65@stream:文件指针
返回值:成功返回读取到的字符的ASCII,失败返回EOF
int getchar(void);
getchar()等同于fgetc(stdin)
int putchar(int c);
putchar(c)等同于fputc(ch, stdout)

3.fgets、fputs、gets、puts(读写一行)

char *fgets(char *s, int size, FILE *stream);
功能:从文件中向s指向的内存中读取字符串,最多读size-1个字符(最后一个用于存‘\0’)。fgets遇到EOF或者换行符的时候就会停止,如果遇到换行符停止的,换行符也会被存储到s中。
参数:@s:指向存储字符的首地址@size:想要读取字符的个数@stream:文件指针
返回值:成功返回s,失败返回NULL
int fputs(const char *s, FILE *stream);
功能:将s中的字符串写入到文件中
参数:@s:被写字符串的首地址@steam:文件指针
返回值:成功返回大于0的值,失败返回EOF
char *gets(char *s);
功能:gets从标准输入stdin读字符串到s
返回值:成功返回时s,遇到'\n'或已输入size-1个字符时返回,总是包含'\0',到文件末尾或出错返回NULL
gets不推荐使用,容易造成缓冲区溢出
int puts(const char *s);
功能:puts将缓冲区s中的字符串输出到stdout,并追加'\n'
返回值:成功时返回输出的字符个数,失败返回EOF

4.fread、fwrite(读写若干个对象)

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:从stream中读取nmemb项数据,每一项的大小是size,将它们存到ptr
参数:@ptr:存储读取到数据的首地址@size:每一项的大小@nmemb:项目的个数@stream:文件指针
返回值:成功返回读取到的项目的个数,如果小于项目的个数就是错误或者到文件的结尾了。
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
功能:将ptr中的数据写入到stream中,写nmemb向,每一项的大小是size
参数:@ptr:被写数据的首地址@size:每一项的大小@nmemb:项目的个数@stream:文件指针
返回值:成功返回项目的个数,失败返回小于项目的个数。

5.feof、ferror(判断文件是否结束或出错)

fread返回值无法区分是到达了文件的结尾还是错误发生了,调用者必须通过feof或者ferror函数来判断。
int feof(FILE *stream);
功能:判断是否读取到了文件的结尾,如果到了文件的结尾将返回真
参数:@stream:文件指针
返回值:如果到了文件的结尾返回真,如果没有到文件结尾返回假int ferror(FILE *stream);
功能:如果在读文件的时候发生了错误,这个函数返回真
参数:@stream:文件指针
返回值:如果发生了错误返回真,如果没有发生错误返回假

6.sprintf、snprintf、fprintf(格式化输出到内存、文件)

int sprintf(char *str, const char *format, ...);
功能:将format控制格式的内容写到str对应的内存中(不会向终端显示)
参数:@str:内存地址@format:和printf的参数完全相同
返回值:成功返回格式化的字符的个数,失败返回负数
int snprintf(char *str, size_t size, const char *format, ...);
功能:将format控制格式的内容写到str对应的内存中(不会向终端显示)
参数:@str:内存地址@size:最多格式化size个字符,其中还包括一个'\0'@format:和printf的参数完全相同
返回值:成功返回格式化的字符的个数,失败返回负数
int fprintf(FILE *stream, const char *format, ...);
功能:将控制格式格式化的字符串写入到文件中
参数:@stream:文件指针@format:控制格式
返回值:成功返回格式化的字符的个数,失败返回负数

7.time、localtime(获取系统时间,将系统时间转为本地时间)

#include 
time_t time(time_t *tloc);
功能:获取自1970-01-01 00:00:00到当前的秒钟数
参数:@tloc:NULL
返回值:成功返回秒钟数,失败返回-1,并置位错误码
struct tm *localtime(const time_t *timep);
功能:将time_t的秒钟转换为tm的结构体(结构体中包含年、月、日...)
参数:@timep:秒钟变量的地址
返回值:成功返回tm结构体指针,失败返回NULL,并置位错误码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) */   //+1int tm_year;   /* Year - 1900 */    //+1900int 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 */ //夏令时};

8.fflush(刷新缓冲区)

int fflush(FILE *fp);
功能:将流缓冲区里的数据写入到实际的文件,Linux下只能刷新输出缓冲区
参数:@fp:文件指针
返回值:成功返回0,失败返回EOF

9.fseek、rewind、ftell(定位文件指针)

int fseek(FILE *stream, long offset, int whence);
功能:设置光标的位置
参数:@stream:文件指针@offset:光标的偏移>0 向后偏移=0 不偏移<0 向前偏移@whence:从那个位置偏移SEEK_SET //从开头开始偏移SEEK_CUR //从当前位置偏移SEEK_END //从结尾的位置偏移
返回值:成功返回0,失败返回-1置位错误码  eg:fseek(fp,0,SEEK_END); //将光标定位到文件的结尾fseek(fp,50,SEEK_SET);//将光标定位到第50个字节的位置fseek(fp,-5,SEEK_CUR);//将光标从当前位置向前偏移5个字节1. 文件a模式打开时,函数fseek无效2. rewind(fp)相当于fseek(fp, 0, SEEK_SET)3. 这3个函数只适用于2G以下的文件
void rewind(FILE *stream);
功能:将光标恢复到文件的开头(rewind = fseek(stream, 0, SEEK_SET))
参数:@stream:文件指针
返回值:无
long ftell(FILE *stream);
功能:返回光标到文件开头的字节数
参数:@stream:文件指针
返回值:成功返回字节数,失败返回-1置位错误码

10.freopen(重定向输入输出流)

在这里插入图片描述

#include int main(int argc, const char **argv)
{if (freopen("1.txt", "w", stdout) == NULL) {perror("freopen");return -1;}printf("stdout --> 1.txt\n");fclose(stdout);printf("end!\n");return 0;
}

三、示例代码

1.fgetc(统计文本文件字符数)

#include int main(int argc, const char **argv)
{int ch;FILE *fp;int count = 0;if (argc < 2) {printf("Usage: %s \n", argv[0]);return -1;}//1ch = fgetc(stdin);if (ch == EOF) {perror("fgetc");return -1;}printf("ch is %c\n", ch);//2if ((fp = fopen(argv[1], "r")) == NULL) {perror("fopen");return -1;}while ((ch = fgetc(fp)) != EOF) {count++;}printf("%s total %d bytes!\n", argv[1], count);fclose(fp);return 0;
}

2.fputc(将a~z写入文件)

#include int main(int argc, const char **argv)
{int ch;int ret;FILE *fp;if (argc < 2) {printf("Usage: %s \n", argv[0]);return -1;}//1ret = fputc('a', stdout);if (ret == EOF) {perror("fputc");return -1;}putchar('\n');//2if ((fp = fopen(argv[1], "w")) == NULL) {perror("fopen");return -1;}for (ch = 'a'; ch <= 'z'; ch++) {fputc(ch, fp);}fclose(fp);return 0;
}

3.fgets(标准输入流写入buff)

#include 
#define N 6int main(int argc, char **argv)
{char buff[N];fgets(buff, N, stdin);printf("%s", buff);return 0;
}

4.fputs(将内存数据输出到标准输出流)

#include int main(int argc, char **argv)
{puts("hello world");  //加换行char buff[] = "hello world\n";  //不加换行fputs(buff, stdout);return 0;
}

5.fread、fwrite(二进制文件读写)

#include 
#include struct stu {char name[15];int age;char sex[10];
};int main(int argc, char **argv)
{	FILE *fp;struct stu s1,s2;int ret;if ((fp = fopen("1.bin", "w+")) == NULL) {perror("fopen");return -1;}strcpy(s1.name, "tanpeng");s1.age = 21;strcpy(s1.sex, "male");ret = fwrite(&s1, sizeof(s1), 1, fp);if (ret == EOF) {perror("fwrite");return -1;}fclose(fp);if ((fp = fopen("1.bin", "r+")) == NULL) {perror("fopen");return -1;}ret = fread(&s2, sizeof(s2), 1, fp);if (ret == EOF) {perror("fread");return -1;}printf("name:%s  age:%d  sex:%s\n", s2.name, s2.age, s2.sex);	 fclose(fp);return 0;
}

6.fflush(刷新流,刷新缓冲区)

#include 
#include int main(int argc, char **argv)
{FILE *fp;int ret;if ((fp = fopen("1.bin", "a+")) == NULL) {perror("fopen");return -1;}ret = fwrite("abcdef", 6, 1, fp);if (ret == EOF) {perror("fwrite");return -1;}fflush(fp);while(1) {sleep(1);}fclose(fp);return 0;
}

7.ftell、fseek、rewind(定位流指针)

#include 
#include int main(int argc, char **argv)
{FILE *fp;int ret;if ((fp = fopen("1.bin", "w")) == NULL) {perror("fopen");return -1;}ret = fwrite("abcdef", 6, 1, fp);if (ret == EOF) {perror("fwrite");return -1;}printf("start fp:%d\n", (int)ftell(fp));ret = fseek(fp, -4, SEEK_CUR);	ret = fwrite("ss", 2, 1, fp);if (ret == EOF) {perror("fwrite");return -1;}printf("fseek fp:%d\n", (int)ftell(fp));rewind(fp);	ret = fwrite("rr", 2, 1, fp);if (ret == EOF) {perror("fwrite");return -1;}printf("rewind fp:%d\n", (int)ftell(fp));fclose(fp);return 0;
}

8.fprintf、sprintf(格式化输出数据到文件、内存,常用sprintf)

#include int main(int argc, char **argv)
{FILE *fp;char buff[40];int year = 2022;int month = 8;int day = 7;if ((fp = fopen("1.txt", "w+")) == NULL) {perror("fopen");return -1;}fprintf(fp, "%d-%d-%d\n", year, month, day);sprintf(buff, "%d-%d-%d", year, month, day);printf("%s\n", buff);fclose(fp);return 0;
}

9.fscanf、sscanf(将文件、内存数据格式化输入,可用作解析字符串)

#include int main(int argc, char **argv)
{	FILE  *fp;char buff[40];int year = 2022;int month = 8;int day = 7;int fyear,fmonth,fday;int syear,smonth,sday;//1.fscanfif ((fp = fopen("1.txt", "w+")) == NULL) {perror("fopen");return -1;}fprintf(fp, "%d-%d-%d", year, month, day);rewind(fp);fscanf(fp, "%d-%d-%d", &fyear, &fmonth, &fday);printf("after fscanf:\n");printf("%d,%d,%d\n", fyear, fmonth, fday);//2.sscanfsprintf(buff, "%d-%d-%d", year, month, day);printf("%s\n", buff);sscanf(buff, "%d-%d-%d", &syear, &smonth, &sday);printf("after sscanf:\n");printf("%d,%d,%d\n", syear, smonth, sday);fclose(fp);	return 0;
}

四、案例源码

1.复制文件1

#include int main(int argc,  char *argv[])
{FILE *fps, *fpd;int ch;if (argc < 3) {printf("Usage : %s  \n", argv[0]);return -1;}if ((fps = fopen(argv[1], "r")) == NULL) {perror("fopen");return -1;}if ((fpd = fopen(argv[2], "w")) == NULL) {perror("fopen");return -1;}while ((ch = fgetc(fps)) != EOF) {fputc(ch, fpd);}fclose(fps);fclose(fpd);return  0;}

2.统计文本文件行数

#include 
#include #define  N  64int main(int argc,  char *argv[])
{FILE *fp;int line = 0;char buf[N];if (argc < 2) {printf("Usage: %s \n", argv[0]);return -1;}if ((fp = fopen(argv[1], "r")) == NULL) {printf("fopen  error\n");return -1;}while (fgets(buf, N, fp) != NULL) {if (buf[strlen(buf)-1] == '\n') line++;}printf("the line of %s is %d\n", argv[1], line);return  0;}

3.复制文件2

#include #define  N  64int main(int argc,  char *argv[])
{FILE *fps, *fpd;int buf[N];int n;if (argc < 3) {printf("Usage : %s  \n", argv[0]);return -1;}if ((fps = fopen(argv[1], "r")) == NULL) {perror("fopen src file");return -1;}if ((fpd = fopen(argv[2], "w")) == NULL) {perror("fopen dst file");return -1;}while ((n = fread(buf, 1, N, fps)) > 0) {fwrite(buf, 1, n, fpd);}fclose(fps);fclose(fpd);return  0;}

4.获取文件长度

#include int main(int argc,  char *argv[])
{FILE *fp;if ((fp = fopen("test.txt", "r+")) == NULL) {perror("fopen");return -1;}fseek(fp, 0, SEEK_END);printf("length is %ld\n", ftell(fp));   return  0;}	

5.按指定格式打印时间

#include 
#include 
#include 
#include int main()
{FILE *fp;int line = 0;char buf[64];time_t t;struct tm *tp;if ((fp = fopen("test.txt", "a+")) == NULL) {perror("fopen");return -1;}while (fgets(buf, 64, fp) != NULL){if (buf[strlen(buf)-1] == '\n') line++;}   while ( 1 ){time(&t);tp = localtime(&t);fprintf(fp, "%02d, %d-%02d-%02d %02d:%02d:%02d\n", ++line, tp->tm_year+1900, tp->tm_mon+1,tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec);fflush(fp);sleep(1);}	  return  0;}

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...