ToB企服应用市场:ToB评测及商务社交产业平台

标题: C语言之输入输出 [打印本页]

作者: 渣渣兔    时间: 2024-10-24 10:25
标题: C语言之输入输出
标准库 IO

输入输出功能并非C语言的组成部分,ANSI标准界说了相关的库函数
输入输出

流stream是与设备关联的数据的源或者目标地。
程序运行时,默认打开 stdin, stdout, stderr
标准 IO 常量
文件流操纵

文件指针指向包含文件信息的布局,包括缓冲区,读写状态等
打开与关闭
  1. FILE *fopen(const char *filename, const char *mode);                    // 打开文件流
  2. /*
  3. mode:
  4. * r, 打开读
  5. * w, 打开或创建写,删除原有内容
  6. * a, 打开或者创建,文件尾追加
  7. * +, 更新,读或写,交叉操作前需要执行fflush或者定位操作
  8.   * r+, 打开文件更新(读和写)
  9.   * w+, 创建文件更新,删除原有内容
  10.   * a+, 打开或创建文件,文件尾更新
  11. * b, 二进制流模式
  12. 应始终检查返回值
  13. */
  14. FILE *freopen(const char *filename, const char *mode, FILE *stream);    // 先关闭再打开文件流
  15. FILE *fdopen(int fd, const char *type);   // POSIX标准,常用于由创建管道和网络通信通道函数返回的描述符,不能直接用 fopen 打开
  16. // type 参数: r, w, a, (+)
  17. // 注意读写模式下读写操作之间需要进行调用定位函数
  18. int fclose(FILE *stream);                                               // 刷新输出缓冲,释放系统缓冲区,关闭流
  19. int fileno(FILE *fp);   // POSIX 标准
复制代码
流的定向

标准IO可用于单字节和多字节字符集,具体由流的定向决定。
  1. #include <stdio.h>
  2. #include <wchar.h>
  3. int fiwde(FILE *fp, int mode);
  4. /*
  5. mode<0, 试图设置为单字节
  6. mode>0,试图设置为多字节
  7. mode=0,不设置定向,返回流的定向
  8. 不会改变已经设置的流定向
  9. */
复制代码
文件操纵函数

重定名
  1. int remove(FILE *stream);                               // 删除文件
  2. int rename(const char *oldname, const char *newname); // 重命名文件
复制代码
临时文件
  1. FILE *tmpfile(void);     // 以`wb+`模式创建临时文件,在关闭或者程序结束时自动删除
  2. // 实现上tmpnam,创建文件,unlink(不会删除内容),文件的关闭会在程序结束中自动进行
  3. char *tmpnam(char s[L_tmpnam]); // 创建不同现有文件名的字符串,NULL返回指向静态数组的指针
  4. // UNIX 优势是不存在时间间隙,避免其他进程创建同名文件
  5. char *mkdtemp(char *temple);  // 创建目录
  6. int mkstmp(char *temple);     // 创建文件,不会自动删除
复制代码
缓冲操纵

标准IO提供缓冲的目标是尽可能镌汰read/write的调用次数
ISO C标准
默认情况
更换缓冲的类型:流被打开之后,且在实行任何操纵之前
  1. int fflush(FILE *stream);                                               // 刷新缓冲区
  2. /*
  3. - 对于输出流,刷新写入缓冲区的内容至目标文件
  4. - 对于输入流,其结果是未定义的
  5. - NULL,刷新所有的缓冲区
  6. 实际使用技巧:每个调试 printf 之后立马调用 fflush
  7. */
  8. int setvbuf(FILE *stream, char *buf, int mode, size_t size);            // 必须在执行读写操作之前设置缓冲
  9. /*
  10. mode:
  11. - _IOFBF 完全缓冲
  12. - _IOLBF 行缓冲
  13. - _IONBF 不设置缓冲
  14. */
  15. void setbuf(FILE *stream, char *buf);     // char buf[BUFSIZ]
  16. /*
  17. - buff为 NULL, 关闭缓冲
  18. - 否则,等价于 `_IOFBF`
  19. // 注意:buf 不要使用自动变量类型,尽量使用系统缓冲区或者动态分配内存
  20. */
复制代码
​#TODO#​检察流缓冲状态 《UNIX高级环境编程》
读写流操纵

字符 IO

​#TODO#​输入输出函数家属 《C和指针》P301
  1. int fgetc(FILE *stream);  // unsigned char 转 int, 兼容EOF
  2. int getc(FILE *stream);   // 等价于 fgetc,注意实现为宏
  3. int getchar(void);        // 等价于 getc(stdin)
  4. int fputc(int c, FILE *stream);
  5. int putc(int c, FILE *stream);  // 等价于 fputc, 注意实现为宏
  6. int putchar(int c);             // 等价于 fputc(stdout)
  7. // 只有fgetc和fputc是函数,其他都是宏
  8. int ungetc(int c, FILE *stream);  // 将字符退回流中,依赖于当前位置
  9. // 不同于写操作,仅涉及流本身而无关设备存储
复制代码
未格式化的行IO
  1. char *fgets(char *s, int n, FILE *stream);  // 自动包含换行符,\n 换为 \0,最多n-1
  2. char *gets(char *s);                        // 不自动包含换行符。没有缓冲区长度参数,可能导致越界;不推荐使用,已废弃
  3. int fputs(const char *s, FILE *stream);     // 不自动包含换行符\n,逐字符输入任意个数换行符
  4. int puts(const char *s);                    // 自动添加换行符\n
  5. ssize_t getline(char **lineptr, size_t *n, FILE *stream);
  6. // 根据输入动态分配内存,无需预先确定输入字符串的最大长度
  7. // 在存储的字符串中将换行符替换为字符串结束符'\0'
复制代码
格式化 IO
  1. int fprintf(FILE *stream, const char *format, ...);
  2. int printf(const char *format, ...);                  // 等价于 `fprintf(stdout, fotmat, ...)`
  3. int sprintf(char *s, const char *format, ...);        // 包含结束符 NUL,无长度参数,可能越界溢出
  4. int snprintf(char *buf, szie_t n, const char *format, ...); // 超出部分截断,出错返回负值
  5. int fdprintf(int fd, const char *format, ...);
  6. // 变长参数列表变体
  7. int vprintf(const char *format, va_list arg);
  8. int vfprintf(FILE *stream, const char *format, va_list arg);
  9. int vsprintf(char *s, const char *format, va_list arg);
复制代码
转换格式:
  1. int fscanf(FILE *stream, const char *format, ...);
  2. int scanf(const char *format, ...);
  3. int sscanf(const char *s, char *format, ...);
  4. int fdscanf(int fd, const char *format,...);
  5. // 变长参数列表变体 ...
复制代码
转换格式
​#TODO#​4种使用场景P309
二进制 IO

直接IO/二进制IO,通常一次处理惩罚一个布局,可以大概处理惩罚null字节和换行符。
留意事项:只能用于同一系统,差异系统的偏移对齐以及存储格式可能差异。因此网络通讯必要指定规范。
  1. size_t fread(void *buffer, size_t size, size_t nobj, FILE *stream);
  2. size_t fwrite(const void *buffer, size_t size, size_t nobj, FILE *stream);
  3. /* 返回值是实际读写的元素的个数而非字节数
  4. fread:少于nobj, 出错或者EOF,需要进一步分辨
  5. fwrite:少于nobj,错误
  6. */
复制代码
内存流

无关文件,直接在缓冲区和主存之间进行字节IO。非常适用于字符串。
Linux支持。
  1. FILE *fmemopen(void *buf, size_t size, const char *type); // buf=null, 读写无意义;对于null字节的处理十分特殊
  2. FILE *open_memstream(char **bufp, size_t sizep);   // 面向字节的流
  3. FILE *open_wmemstream(wchar_t **bufp, size_t *sizep);  // 面向宽字节的流
复制代码

文件定位函数

  1. int fseek(FILE *stream, long offset, int origin);
  2. /*
  3. - 二进制文件
  4.   - origin
  5.     - `SEEK_SET` 文件开始处
  6.     - `SEEK_CUR` 当前位置
  7.     - `SEEK_END` 文件结束处,可能不支持
  8. - 文本文件
  9.   - `SEEK_SET`;offset是 0 或者 `ftell`返回值
  10.   - `SEEK_CUR`/`SEEK_END`:offset只能是 0
  11. 注意事项
  12. - 行末指示符将被清除
  13. - 退回的字符将被丢弃
  14. - 更新模式中的读写操作切换
  15. */
  16. long ftell(FILE *stream);
  17. void rewind(FILE *stream);    // 重置为起始位置
  18. //等价于 `fseek(stream, 0L, SEEK_SET); clearerr(stream);`
复制代码
  1. // off_t, 大于32位 UNIX 标准
  2. off_t ftello(FILE *fp);
  3. int seeko(FILE *fp, off_t offset, int origin);
复制代码
  1. // fpos_t ISO C标准,更加通用
  2. int fgetpos(FILE *stream, fpos_t *ptr);
  3. int fsetpos(FILE *stream, const fpos_t *ptr);
复制代码

错误处理惩罚函数

发生错误或者到达文件尾时会设置状态指示符
整型表达式 errno 包含错误编号,界说在
  1. /* ----- 流错误 -----*/
  2. int feof(FILE *stream);     // 流设置了文件结束指示符,返回非0值
  3. int ferror(FILE *stream);   // 流设置了错误指示符,返回非0值
  4. int clearerr(FILE *stream); // 清除流的所有指示符
复制代码
  1. #include <string.h>
  2. char *strerror(int crrno);  // 映射错误信息
  3. #include  <stdio.h>
  4. int perror(const char *s);  // 打印字符串和 errno 错误信息
  5. // 类似于 fprintf(stderr, "%s: %s\n", s, "error essage");
复制代码
标准IO的替代

标准IO 的效率不高,调用行IO必要进行两次数据的复制
适用于嵌入式系统的更低内存要求的实现

参考


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4