标准io\文件io和库

本文详细介绍了C语言中的标准I/O,包括标准输入、输出、错误流,以及打开、关闭、读写文件的操作。讨论了缓冲机制、文件描述符、错误处理、文件定位和权限管理。同时,还对比了标准I/O与文件I/O的区别,提到了库的概念和库的使用,包括静态库和共享库的创建及链接。
摘要由CSDN通过智能技术生成

标准io
标准I/O介绍

概念:
一组相关数据的有序集合

文件类型:
常规文件 r
目录文件 d
字符设备文件 c
块设备文件 b
管道文件 p
套接字文件 s
符号链接文件 l

UNIX基础知识-系统调用和库函数
在这里插入图片描述
标准I/O由ANSI C标准定义
主流操作系统上都实现了C库
标准I/O通过缓冲机制减少系统调用,实现更高的效率

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

struct _IO_FILE {
   
  int _flags;		/* High-order word is _IO_MAGIC; rest is flags. */
#define _IO_file_flags _flags

  /* The following pointers correspond to the C++ streambuf protocol. */
  /* Note:  Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
  char* _IO_read_ptr;	/* Current read pointer */
  char* _IO_read_end;	/* End of get area. */
  char* _IO_read_base;	/* Start of putback+get area. */
  char* _IO_write_base;	/* Start of put area. */
  char* _IO_write_ptr;	/* Current put pointer. */
  char* _IO_write_end;	/* End of put area. */
  char* _IO_buf_base;	/* Start of reserve area. */
  char* _IO_buf_end;	/* End of reserve area. */
  /* The following fields are used to support backing up and undo. */
  char *_IO_save_base; /* Pointer to start of non-current get area. */
  char *_IO_backup_base;  /* Pointer to first valid character of backup area */
  char *_IO_save_end; /* Pointer to end of non-current get area. */

  struct _IO_marker *_markers;

  struct _IO_FILE *_chain;

  int _fileno;
#if 0
  int _blksize;
#else
  int _flags2;
#endif
  _IO_off_t _old_offset; /* This used to be _offset but it's too small.  */

#define __HAVE_COLUMN /* temporary */
  /* 1+column number of pbase(); 0 is unknown. */
  unsigned short _cur_column;
  signed char _vtable_offset;
  char _shortbuf[1];

  /*  char* _save_gptr;  char* _save_egptr; */

  _IO_lock_t *_lock;
#ifdef _IO_USE_OLD_IO_FILE
};

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

文本流和二进制流在不同的系统中最大的区别是换行符
Windows
windows是区分文本流和二进制流的
二进制流: 换行符 ‘\n’ 对应的是一个字符
文本流: 换行符 ‘\r’ ‘\n’ 对应的是两个字符

linux中并不区分二进制流和文本流,或者说linux中就是二进制流
Linux: 换行符 ‘\n’

标准I/O – 流的缓冲类型
1.全缓冲,当流的缓冲区中满的时候才执行文件的操作,这是写的时候;
读的时候,第一次读的时候,首先会把第一批数据都读到缓冲区里,然后每次从缓冲区中读取内容,当缓冲区空的时候,才会再从实际的文件中读一批数据进来,当打开一个普通文件的时候,默认的是全缓冲;
2.行缓冲,当输入和输出遇到换行符“\n“时,进行i/o操作,当流和一个终端关联时,就是典型的行缓冲,其实就是标准输入和标准输出流,因为标准输入和标准输出都是和终端相关联的,所以他们的默认类型都是行缓存;
3.无缓冲,数据直接写入文件,流不进行缓冲,标准错误流就是典型的无缓冲;

标准i/o—stdin/stdout/stderr
标准i/o预定义了三个流,程序运行时会自动打开,分别是:

标准输入流 文件描述符:0 STDIN_FILENO stdin
标准输出流 文件描述符:1 STDOUT_FILENO stdout
标准错误流 文件描述符:2 STDERR_FILENO stderr
标准i/o就是标准C中定义好的一组用来输入输出的API函数

标准I/O – 打开流
下列函数可用于打开一个标准I/O流:
FILE *fopen (const char *path, const char *mode);
成功时返回流指针;出错时返回NULL

mode参数:
“r” 或 “rb” 以只读方式打开文件,文件必须存在。
“r+” 或 ”r+b” 以只读方式打开文件,文件必须存在。
“w” 或 “wb” 以只写方式打开文件,若文件存在则文件长度清为0。若文件不存在则创建。
“w+” 或 “w+b” 以读写方式打开文件,其他同”w”。
“a” 或 “ab” 以只写方式打开文件,若文件不存在则创建;向文件写入的数
据被追加到文件末尾。
“a+” 或 “a+b” 以读写方式打开文件。其他同”a”
这里的b参数表示二进制方式打开文件,linux下忽略改参数;

创建新文件的权限:
1.fopen() root用户下,创建的文件访问权限是0666(rw-rw-rw),0666中的”0“表示八进制;
2.linux系统中umask设定会影响文件的访问权限,其规则为(0666&~umask)例如:
fopen的默认权限是0666,root下的掩码是022,分别换算为二进制后是:110 110 110和~1010(波浪号是按位取反的意思)=111 101 101;经过&运算后得:110 100 100,换算八进制后是0644;
用户可以通过umask函数或者命令修改相关设定

标准I/O – 处理错误信息
extern int errno;
void perror(const char *s);
char *strerror(int errno);

errno 存放错误号,由系统生成
perror先输出字符串s,再输出错误号对应的错误信息
strerror根据错误号返回对应的错误信息

标准I/O – 错误信息处理 – 示例1

#include <stdio.h>
int main(int argc,  char *argv[])
{
   
   FILE *fp;
    
   if ((fp = fopen(“test.txt”, “r+)) == NULL) {
   
       perror(“fopen”);
       return -1;
   }

标准I/O – 错误信息处理 – 示例2

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main(int argc,  char *argv[])
{
   
   FILE *fp;
   if ((fp = fopen(“test.txt”, “r+)) == NULL) {
   
       printf(“fopen: %s\n”, strerror(errno));
       return -1;
   }

标准I/O – 关闭流

int fclose(FILE *stream);
fclose()调用成功返回0,失败返回EOF,并设置errno
流关闭时自动刷新缓冲中的数据并释放缓冲区
当一个程序正常终止时,所有打开的流都会被关闭。
流一旦关闭后就不能执行任何操作

标准I/O – 读写流
流支持不同的读写方式:
读写一个字符:fgetc()/fputc()一次读/写一个字符
读写一行:fgets()和fputs()一次读/写一行
读写若干个对象:fread()/fwrite() 每次读/写若干个对象,而每个对象具有相同的长度

标准I/O – 按字符输入
下列函数用来输入一个字符:
#include <stdio.h>
int fgetc(FILE *stream);
int getc(FILE *stream); //fgetc和getc的功能是完全一样的,位要不同的是getc啊在标准C中被定义为一个宏,在使用的时候有一定的局限性;fgetc这里的“f”是function
int getchar(void);
成功时返回读取的字符;若到文件末尾或出错时返回EOF
getchar()等同于fgetc(stdin)
getc和fgetc区别是一个是宏一个是函数

标准I/O – fgetc – 示例

  int  ch;
  ch = fgetc(stdin);
  printf(%c\n”, ch);

  FILE  *fp;
  int  ch, count = 0;
  if ((fp  =  fopen(argv[1], “r”)) == NULL)  {
    
    perror(“fopen”);  return  -1;
  }
  while ((ch  =  fgetc(fp)) != EOF) {
     
    count++; 
  }
  printf(“total  %d bytes\n”, count);

标准I/O – 按字符输出
下列函数用来输出一个字符:
#include <stdio.h>
int fputc(int c, FILE *stream);
int putc(int c, FILE *stream); //这里的fputc和putc同fgetc和getc
int putchar(int c);

成功时返回写入的字符;出错时返回EOF
putchar©等同于fputc(c, stdout)

标准I/O – fputc – 示例

fputc(‘a’, stdout);
  putchar(‘\n’);

  FILE  *fp;
  int  ch;
  if ((fp  =  fopen(argv[1], “w”)) == NULL)  {
    
     perror(“fopen”);  return  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值