乱读天书, 不求甚解
周祎骏的个人云笔记
Toggle navigation
乱读天书, 不求甚解
主页
Linux:系统配置
Linux:用户管理
Linux:优化排错
Linux:进程调度
Linux:文件系统
Linux:网络
Linux:系统服务
Linux:安全
Linux:内核
容器:Docker
容器:containerd
容器编排:Kubernetes
IAC:Terraform
大数据:Hadoop
大数据:Zookeeper
大数据:Hbase
消息队列:rsyslog
消息队列:kafka
数据库:MySQL
数据库:MongoDB
搜索引擎:Elasticsearch
时序数据库:OpenTSDB
网站服务:Nginx
编程:Bash
编程:Perl
编程:Python
编程:C
编程:JAVA
编程:Rust
版本控制:gitlab
知识管理:docusaurus
常用小工具
关于我
标签
C 2.01 函数库stdio.h
2018-06-17 08:23:04
72
0
0
admin
> 标准的IO库,输入输出,以文件对象的方式读写文件,操作文件;popen等 #基本介绍 **库变量** size_t 就是unsigned int 的typedef,一般用于指针 **宏** NULL 空指针 EOF 表示已经达到文件末尾的负数 FILE 存储文件流信息的对象类型 BUFSIZ setbuf函数使用的缓冲区大小 stderr/stdin/stdout 错误输出/标准输入/标准输出 #函数 ##关于显示 **int printf(const char *format, ...)**: 格式化输出 **int sprintf(char *str, const char *format, ...)**: 格式化输出赋值给一个字符串 ``` int a = 12345; printf("aaa%6dbbb\n",a); ``` ``` %d 向右对其,对应int %ld 向右对其,long %-d 左对齐 %6d 起码6个字符宽度 %6.1f 对应float,起码6个字符宽度,小数点后1位 %u 10进制无符号 %c 对应char %s 对应string %% 就是%本身 %x 16进制 ``` ``` #include <stdio.h> main() { char string[20]; sprintf(string,"aaa%dbbb\n",121); printf("%s",string); } ``` *** **int scanf(const char *format, ...)**:从标准输入读取格式化输入,赋值给给定的参数(参数必须是指针),返回匹配成功的个数(0表示一个都不匹配,EOF表示都匹配) **int sscanf(const char *str, const char *format, ...)**: 从字符串中读取而不是从标准输入读取。 ``` #include <stdio.h> main() { int day,year; char month[20]; int match_number = scanf("%d %s %d",&day,month,&year); printf("d=%d,m=%s,y=%d,match_number=%d\n",day,month,year,match_number); } ``` ``` #include <stdio.h> main() { char *line = "12 dec 2018"; int day,year; char month[20]; int match_number = sscanf(line,"%d %s %d",&day,month,&year); printf("d=%d,m=%s,y=%d,match_number=%d\n",day,month,year,match_number); } ``` *** **int fprintf(FILE *stream, const char *format, ...)** 将格式化输出写到文件中 **int fscanf(FILE *stream, const char *format, ...)** 从文件中读取格式化输入 *** ##关于文件对象 **FILE *fopen(const char *filename, const char *mode)** 用指定模式打开文件,失败会返回NULL 文件需存在:r读,r+ 读写,a 追加 允许创建新文件 w写,w+ 读写,a+追加 b表示二进制 **FILE *freopen(const char *filename,const char *type,FILE *fp)** 重定向,失败返回NULL **FILE *fdopen(int fd,const char *type** 从文件句柄获得FILE对象 **int fclose(FILE *stream)** 关闭文件句柄,刷新缓冲区 **int fileno(FILE *fp)** 获取文件对象的文件句柄 *** ##关于读写 **int getchar(void)**: 从标准输入中读取一个无符号字符 **int putchar(int char)**: 将一个无符号字符写入到标准输出 ``` #include <stdio.h> main() { int c; while( (c = getchar()) != EOF ) putchar(c); } ``` **int getc(FILE *stream)** 从文件读取一个字符,返回EOF表失败 **int fgetc(FILE *stream)** 从文件读取一个字符,返回EOF表失败(肯定是函数,getc可能是宏) **int putc(int char, FILE *stream)** 往文件写一个字符,返回EOF表失败 **int fputc(int char, FILE *stream)** 往文件写一个字符,返回EOF表失败(肯定是函数,putc可能是宏) **char *fgets(char *str, int n, FILE *stream)** 读取一行,赋值给str,最多读n个字符 **char *gets(char *str)** 从标准输入读取一行,会去掉换行符 gets 函数有安全隐患,不要用,因为它不指定buf长度,很可能越界 **int fputs(const char *str, FILE *stream)** 向文件写一行 **int puts(const char *str)** 输出一行到标准输出,会加上换行符 **int ferror(FILE *stream)** 检查上一次对该文件的输入输出是否成功,返回0表示没有错误 **int feof(FILE *fp)** 检查文件流是否到尾部了 **void clearerr(FILE *fp)** 清除出错标志和文件结束标志 ``` #include <stdio.h> #include <stdlib.h> //exit 函数需要这个库 main(int argc, char *argv[]) { FILE *read_file,*write_file; if (argc != 3 ) { fprintf(stderr,"%s,ERROR arg numbers\n",argv[0]); exit(1); } if ( (read_file = fopen(argv[1],"r")) == NULL) { fprintf(stderr,"%s,Failed to read %s",argv[0],argv[1]); exit(1); } if ( (write_file = fopen(argv[2],"w")) == NULL) { fprintf(stderr,"%s,Failed to writr %s",argv[0],argv[2]); exit(1); } int c; while ( (c=getc(read_file)) != EOF ) { putchar(c); putc(c,write_file); } if ( ferror(read_file) || ferror(write_file) ) { fprintf(stderr,"%s,Failed to copy file %s to %s",argv[0],argv[1],argv[2]); exit(1); } fclose(read_file); fclose(write_file); exit(0); } ``` **int ungetc(int c FILE *fp)** 把一个字符送回文件流,失败返回EOF。 ###读写定位 **long ftell(FILE *fp);** 获得当前位置,失败返回-1L **int fseek(FILE *fp,long offset,int flag)** 修改当前位置,失败返回非0 flag: SEEK_CUR 当前位置 SEEK_SET 起始位置 SEEK_END 结束位置 **void rewind(FILE *fp)** 将当前位置重新定位到起始位置 ####将位置存入pos对象,方便之后再重定向到此处: ``` fpos_t *pos int fgetpos(FILE *fp,fpos_t *pos); int fsetpos(FILE *fp,const fpos_t *pos); ``` ###二进制读写 **size_t fread(void *obj, size_t size, size_t obj_num, FILE *fp)** **size_t fwrite(const void *obj, size_t size, size_t obj_num, FILE *fp)** 例子: 将一个数组的2-5个元素写到文件上 ``` int a[10]; if (fwrite(&a[2], sizeof(int), 4, fp) != 4) printf("error\n"); ``` 将一个结构写到文件上 ``` struct { ... } obj if (fwrite(&obj, sizeof(obj), 1, fp) != 1) printf("error\n"); ``` *** ##关于缓冲 内核通常都会对读写有一些缓冲,一般错误输出不缓冲,普通交互行缓冲,不涉及交互的全缓冲 **void setbuf(FILE *fp,char *buf)** 改变一个文件流的缓冲用的字符串空间,其长度就是BUFSIZ,如果要关闭缓冲,就把buf设置为NULL **intsetvbuf(FILE *fp ,char *buf,int mode,seze_t size)** 改变一个文件流的缓冲模式,失败返回-1 mode: _IOFBF 全缓存 _IOLBF 行缓存 _IONBF 不缓存 如果不是 不缓存的选项,buf设置为NULL的话,会给予默认值 **int fflush(FILE *stream)** 刷新缓冲区 *** ##关于文件操作 **int rename(const char *old_filename, const char *new_filename)** 改名字 **int remove(const char *filename)** 删除文件 ``` main() { rename("./a.c","./b.c"); remove("./c.c"); } ``` ##关于临时文件 **FILE *tmpfile(void)** 创建临时文件,返回文件指针,失败返回NULL,关闭文件或程序结束时会自动删除。 **char *tmpnam(char *name)** 生成临时文件名放在name里,name 长度为L_tmpnam (因为安全隐患,不建议用) **char *tempnam(const char *dir ,sonst char *prefix)** 如果有环境变量TMPDIR用这个,没有用*dir,dir是NULL就用P_tmpdir,通常就是/tmp (因为安全隐患,不建议用) prefix最多5个字符,作为前缀 > 这两个函数有安全隐患是因为生成了临时文件却没有创建文件,没有做到原子性,如果在生成文件名和创建文件之间的空隙出点什么事。。。 要安全,建议使用stdlib.h的mkstemp *** ##用popen 获取命令行输出 **FILE *popen(const char *cmd string, const char *type)**:type为“r”或者"w",成功返回文件对象,失败返回NULL **int pclose(FILE *fp)**: 关闭文件对象,成功返回命令终止状态,失败返回-1 pclose 返回的终止状态类似于wait.h里面返回的状态,所以这里引用了wait.h和WEXITSTATUS宏 ``` #include <stdio.h> #include <wait.h> main() { FILE *f; f = popen("ls -l ","r"); int c; while ((c=getc(f)) != EOF) putchar(c); printf("result=%d\n",WEXITSTATUS(pclose(f))); } ```
上一篇:
C 2.00 函数库limit.h
下一篇:
C 2.02 函数库string.h
文档导航