linux系统编程 -- 标准io

相关概念

1. **标准I/O的概念**:
   - 标准I/O是由Dennis Ritchie在1975年为C语言设计的一套库,它是ANSI C标准的一部分。
   - 标准I/O提供了一组函数,用于简化文件I/O操作,包括输入和输出。

2. **标准I/O的头文件**:
   - `stdio.h`是标准I/O库的头文件,它包含了进行输入输出操作所需的函数声明。

3. **文件的概念和作用**:
   - 在Linux操作系统中,一切都是文件,包括设备文件、普通文件等。
   - 文件用于存储数据和指令。

4. **Linux中文件的类型**:
   - Linux文件系统支持多种类型的文件,包括:
     - 普通文件(-)
     - 目录(d)
     - 符号链接(l)
     - 管道(p)
     - 套接字(s)
     - 字符设备文件(c)
     - 块设备文件(b)

5. **标准I/O的缓存机制**:
   - 标准I/O通常使用缓存机制来提高文件I/O的效率,减少系统调用的次数。

### 缓冲机制类型:

1. **行缓冲(Line Buffering)**:
   - 主要用于终端(如控制台)的`stdout`输出。
   - 缓冲区大小通常为1KB。
   - 刷新条件:
     - 遇到换行符`\n`时自动刷新。
     - 缓冲区满时自动刷新。
     - 程序结束时自动刷新。
     - 通过`fflush(stdout);`手动刷新。

2. **全缓冲(Full Buffering)**:
   - 主要用于文件读写操作。
   - 缓冲区大小通常为4KB(4096字节)。
   - 刷新条件:
     - 缓冲区满时自动刷新。
     - 程序结束时自动刷新。
     - 通过`fflush(fp);`手动刷新,其中`fp`是指向文件的指针。

3. **无缓冲(Unbuffered)**:
   - 主要用于错误信息的输出,如`stderr`。
   - 不对数据进行缓存,直接输出。
   - 通常用于紧急或错误信息的输出,以确保信息能够立即显示。

### 缓冲区的刷新:

- **自动刷新**:在特定条件下(如行缓冲遇到`\n`,全缓冲区满),缓冲区会自动刷新。
- **手动刷新**:通过调用`fflush`函数,可以手动清空缓冲区,确保数据立即输出。

### 缓冲区大小的设置:

- 缓冲区的大小通常是固定的,但某些实现可能允许通过特定的函数或方法来调整缓冲区的大小。

### 应用场景:

- **行缓冲**:适用于需要即时反馈的人机交互场景,如命令行工具的输出。
- **全缓冲**:适用于文件读写操作,可以提高I/O效率。
- **无缓冲**:适用于错误处理,确保错误信息能够立即输出,不丢失。

### 调试和测试:

- 使用工具如`gdb`可以查看`FILE`结构体的状态,了解缓冲区的使用情况。
- 通过写入数据并观察其输出时机,可以测试缓冲区的工作机制。

### 注意事项:

- 在使用标准I/O进行文件操作时,了解缓冲机制对于优化程序性能和确保数据正确性非常重要。
- 适当使用`fflush`可以控制数据的输出时机,尤其是在需要同步输出或处理大量数据时。

通过以上总结,你可以更好地理解C语言标准I/O库中的缓冲机制,并在实际编程中合理利用这些机制来优化程序的I/O性能和行为。
 

6. **流的概念**:
   - 流是数据的序列,可以是输入流或输出流。
   - 在C语言中,`FILE`结构体定义了流,而`FILE*`(流对象或文件流指针)用于指向流。

7. **流的分类**:
   - 文本流:以文本形式处理数据,通常使用ASCII或UTF-8编码。
   - 二进制流:以二进制形式处理数据,不进行任何转换。

8. **标准I/O的函数**:
   - 一些常用的标准I/O函数包括:
     - `printf`和`scanf`:用于格式化输出和输入。
     - `sprintf`:将格式化的数据写入字符串。
     - `getchar`和`putchar`:读取和写入单个字符。
     - `fgets`和`fputs`:读取和写入字符串。
     - `fread`和`fwrite`:读取和写入数据块。
     - `ftell`:获取当前文件位置指针的位置。
     - `rewind`:将文件位置指针重置到文件开头。
     - `fseek`:设置文件位置指针到指定位置。

9. **标准I/O的预定义流**:
   - `stdin`:标准输入流,通常用于从键盘读取数据。
   - `stdout`:标准输出流,通常用于向显示器输出数据。
   - `stderr`:标准错误流,用于输出错误信息。

10. **`man`命令的使用**:
    - `man`命令用于查看Linux下的手册页,提供有关命令、系统调用和库函数的信息。
    - `man`后面可以跟数字和命令名来查看不同部分的手册,例如:
      - `man 1 command`:查看用户命令的帮助。
      - `man 2 syscall`:查看系统调用的帮助。
      - `man 3 function`:查看标准库函数的帮助。

以上是C语言编程中进行输入输出操作的基础。

文件操作步骤:

1,打开文件  FILE 
2,io操作,,读写操作
3,关闭文件  

下面介绍常用的相关函数

1.fopen

FILE *fopen(const char *path, const char *mode);
功能:
打开一个文件并建立一个流
参数:
path:要打开文件的路径
mode:
r 只读
文件不存在报错
文件存在则只读打开

r+ 读写
文件不存在报错
文件存在则读写打开

w 只写
文件不存在则创建
文件存在则清0只写打开

w+ 写读
文件不存在则创建
文件存在则清0写读打开

a 追加可写
文件不存在则创建
文件存在则追加只写打开     定位到文件最后增加内容。

a+ 追加读写
文件不存在则创建
文件存在则追加读写打开

返回值:
成功返回建立的文件流指针
失败返回NULL

2. fputc

int fputc(int c, FILE *stream);
功能:
向流中写入一个字符
参数:
c:要写入的字符
stream:文件流指针
返回值:
成功返回写入的字符ASCII码值
失败返回EOF

3.fgetc

 int fgetc(FILE *stream);
功能:
从流中读取一个字符

参数:
stream:文件流指针
返回值:
成功返回读到字符的ASCII码值
读到文件末尾返回EOF
失败返回EOF -1
c= fgetc(stdin);
fputc(c,stdout);
获取键盘上面的输入,显示到屏幕。

4.feof

feof() 函数判断
int feof(FILE *stream);
功能:判断当前参数stream的文件流指针是否到达文件结尾。
  如果到达文件结尾则返回真,否则返回假
  注意:该操作一定要在一次IO操作之后判断。
参数:stream 要判断结尾的文件流对象
返回值:成功到达结尾是 真
否则 是假 

5.fgets

char *fgets(char *s, int size, FILE *stream);
功能:从stream流对象关联的文件中获取size大小字节的文本数据
  并存储到s对应的本地内存(栈区数组,堆区内存)
参数: s 要存储数据的本地内存
   size 要获取的数据长度,单位字节。
   stream 要获取的目标文件流对象,
    可以是stdin ,程序会阻塞等待
如果是普通文件fp 则指向文件第一行数据
返回值:成功 返回指向有效数据的首地址,一般等于s的地址
    失败 或者 文件末尾 NULL; 

6.fputs

 int fputs(const char *s, FILE *stream);
功能:从s所在的本地内存中获取一行数据,并写入stream对应的文件
      流对象。
参数: s 要写的信息,一般是固定的字符串或者有数据的数组。
   stream 要写入的目标文件流对象

返回值:成功 nonnegative number on success
失败 -1;
char buf[50];
gets(buf);

7.补充:fgets和gets的区别

 1.gets是危险的,因为没有规范读
  到数据的上限
2.gets会去掉从终端读入的\n字符
3.fgets会读到n个数据,如果n个
  数据中存在\n字符则立即停止当
  前的读取操作
4.fgets不会去掉从流中读到的\n字

 8.二进制文件读写:  fread()/fwrite()

读:
size_t  fread(void  *ptr,  size_t size, size_t nmemb, FILE *stream);
功能:从指定的stream流对象中获取nmemeb个大小为size字节的数据块到ptr
      所在的本地内存中。
参数:ptr 要存储数据的本地内存一般是数组或者结构体指针
  size 单个数据块的元数据大小。最小单元的大小
  nmemb 要获取的数据块的个数,拷贝的数据块个数。
  stream 要获取数据的源文件流对象,如果是stdin表示从
  键盘获取数据,如果是fp文件则表示从普通文件获取。
返回值:成功 小于等于nemeb的整数,表示获取的数据长度
失败 小于0,结尾 0;

写:
size_t fwrite(const void  *ptr,  size_t  size,size_t nmemb, FILE *stream);
功能:从ptr所在本地内存中取出nmemb个大小为size的数据块写入到stream流对应
     的文件流对象中。
参数:ptr 要写的数据块地址,一般是数组或者结构体指针
  size  要写的数据块元数据大小,单位是字节
  nmemb 要写的数据块的个数
  stream 要写的目标文件流对象。如果是stdout则表示数据会
  写到终端屏幕显示,如果是fp的普通文件则会写入到文件中。

返回值:成功 小于等于nmemb 的个数。
失败 <0

 标准IO之文件定位:fseek()   ftell()  rewind()

1.fseek

int fseek(FILE *stream, long offset, int whence);
功能:将stream流文件中的文件指针从whence位置开始
      偏移offset字节的长度。
参数:stream  要移动文件指针的目标文件流对象。
  注意:不支持设备文件,一般用于普通文件。
  offset  要在文件内偏移的距离,单位字节。
     如果值为整数,则向文件末尾偏移
  如果值为负数,则向文件开头偏移
  whence  偏移的起始位置,由系统定义的三个宏开始。
   SEEK_SET  文件的开头位置 
SEEK_CUR  文件的当前位置
SEEK_END  文件的末尾位置

返回值:
成功: 返回 0
失败:  -1;

如果从文件的指定位置向后偏移过程中已经超过了文件
的当前末尾位置,则会自动以'\0'来填充文件内容,从
而形成一种被称为"空洞文件" 的特殊文件。

2.rewind

rewind()  等效于:fseek(stream,0L,SEEK_SET);

long ftell(FILE *stream);rewind(fp);
功能:获取当前文件流指针的具体位置,一般以文件
     开头到当前指针的字节数为返回值。
参数:stream 要返回指针距离的文件流对象
返回值:成功 获取到的距离长度,单位是字节
失败 -1;
 

 以上的所有函数都可以在man手册中找到,关于参数及返回值会有更详细的描述。

  • 23
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值