c语言 标准i o 流,C的标准I/O库

标准I/O库.

这个东东一般只要上个C语言的人都学过.比如printf函数.这些东东,大都是建立在一个叫FILE的对象上.

下面我清数下这此函数.(可能还有很多没有!)

int fwide(FILE *fp,int mode);      //流处理是宽字节还是字节的或者无字节的,看下面的_IO_fwide_maybe_incompatible

void setbuf(FILE* fp,char *restrict buf);       //设置文件流是是行缓冲,还是全缓冲,一般是全缓冲,但与具体设备相关就不一定了.

int setvbuf(FILE* fp,char *restrict buf,int mode,size_t size);//同上,但是指出是什么样的缓冲

int fflush(FILE *fp);   //刷新缓冲区

FILE* fopen(const char *restrict pathname,const char *restrict type);     //看下篇

FILE* freopen(const char *restrict pathname,const char * restrict type,FILE *restrict fp);//相当于先关闭,再打开一次

FILE* fdopen(int filedes,const char *type);//根据文件描述符打开文件流

int getc(FILE *fp);     //下面已经有实现宏

int fgetc(FILE *fp);    //功能和getc一样,但是它是个函数,而getc是一个宏

int getchar(void);     //他从stdin里取数据,看下面_IO_stdin宏

//以上三个函数成功都返回下一个字符

#define _IO_feof_unlocked(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0)      //是否文件结束

#define _IO_ferror_unlocked(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0)    //判断标志,是否出错

int ferror(FILE *fp);    //判断是否出错 ,具体看下面

int feof(FILE *fp);      //判断是否到文件尾

void clearerr(FILE *fp);  //清除上面两个标志

ungetc(int c,FILE *fp); //倒序取流的字节

int putc(int c,FILE *fp);     //_IO_putc_unlocked

int fputc(int c,FILE *fp);

int putchar(int c);

char* fgets(char *restrict buf,int n,FILE*restrict fp);//看下篇,其实是用_IO_putc_unlocked实现的

char* gets(char *buf);                  //这个函数和上面基本一样,取的设备是stdout,但没有缓冲区大小,可能溢出

//注意这里是结构读写,并不是字节读写.nobj对象个数,size表示一个对象的大小,ptr为缓冲指针

size_t fread(void *restrict ptr,size_t size,size_t nobj,FILE *restrict fp);    //看下篇

size_t fwrite(const void* restrict ptr,size_t size,size_t nobj,FILE *restrict fp);

long ftell(FILE *fp);          //返回流的当前位置,我们现在看到了FILE结构,所以这个很简单吧.

int fseek(FILE *fp,long offset,int whence);   //设置流的当前位置

void rewind(FILE *fp);     //直接设置流到起始位置,无返回值.

off_t ftello(FILE *fp);         //可以看出这两个函数和上面的两个一样,只是long 变成了off_t,实际他功能确实如此

int fseeko(FILE *fp,off_t offset,int whence);

int fgetpos(FILE *restrict fp,fpos_t *restrict pos);  //这两个函数和fseek及ftell,只是他们将位置放到了参数内部

int fsetpos(FILE *fp,const fpos_t *pos);              //并且文件偏移类型也由long -->fpos_t了.

//下面八个格式化输出

int printf(const char *restrict format,...);         //格式化输出到stdout里

int fprintf(FILE *fp,const char *restrict format,...);     //格式化输出到fp

int sprintf(char *restrict buf, const char *restrict format,...);      //格式化输出到字符数组里

int snprintf(char *restrict buf,size_t n,const char* restrict format,...); //格式化输出到指定长度的数组里

int vprintf(const char *restrict format ,va_list arg);           //这四个函数和上面一模一样,只是将va_list arg代替...,

int vfprintf(FILE* restrict fp,const char *restrict format,va_list arg);      //其实实际编译后台也会作此转换的.

int vsprintf(char * restrict buf,const char *restrict format,va_list arg);

int vsnprintf(char * restrict buf,size_t n,const char *restrict format,va_list arg);

//再下面六个格式化输入

int scanf(const char *restrict format,...);      //从stdin里输入,不用说.记得...代表是地址.

int fscanf(FILE *restrict fp,const char *restrict format,...);              //上面一样,stdin变成了fp

int sscanf(const char *restrict buf,const char *restrict format,...);     //从一数组里格式化输入

int vscanf(const char *restrict format,va_list arg);                //同上

int vfscanf(FILE *restrict fp,const char *restrict format,va_list arg);

int vsscanf(const char *restrict buf,const char *restrict format,va_list arg);

int fileno(FILE* fp);    //看_IO_FILE就知道,int _fileno;    这是内部成员,所以一个宏就可以实现//获取文件描述符

char *tmpnam(char *ptr);      //产生一个临时文件

FILE *tmpfile(void);          //产生一个流的临时文件

char *tempnam(const char* directory,const char *prefix);     //指定了具体的路径,和前缀,但前缀最多只能5个字符

int mkstemp(char *template);//返回一临时文件的文件描述符.它的前半部应该是先打开临时文件,并返回描述符.

//以下是他最有用的一个文件,来自于glibc-->libio.h,定义了几乎所有重要结构,看我解释

#ifndef _IO_STDIO_H

#define _IO_STDIO_H

#include //这个不管,一些全局配置,关于下面这个变量的实际定义

/* ALL of these should be defined in _G_config.h */

#define _IO_pos_t _G_fpos_t /* obsolete */

#define _IO_fpos_t _G_fpos_t

#define _IO_fpos64_t _G_fpos64_t

#define _IO_size_t _G_size_t

#define _IO_ssize_t _G_ssize_t

#define _IO_off_t _G_off_t

#define _IO_off64_t _G_off64_t

#define _IO_pid_t _G_pid_t

#define _IO_uid_t _G_uid_t

#define _IO_iconv_t _G_iconv_t

#define _IO_HAVE_SYS_WAIT _G_HAVE_SYS_WAIT

#define _IO_HAVE_ST_BLKSIZE _G_HAVE_ST_BLKSIZE

#define _IO_BUFSIZ _G_BUFSIZ

#define _IO_va_list _G_va_list

#define _IO_wint_t _G_wint_t

#ifdef _G_NEED_STDARG_H                                        //是否要参数文件,即,它主要实现了va_list,va_start,va_arg,va_end;

/* This define avoids name pollution if we're using GNU stdarg.h */

# define __need___va_list

# include # ifdef __GNUC_VA_LIST

#  undef _IO_va_list

#  define _IO_va_list __gnuc_va_list

# endif /* __GNUC_VA_LIST */

#endif

#ifndef __P                  //这个我也不知道

# if _G_HAVE_SYS_CDEFS

#  include # else

#  ifdef __STDC__

#   define __P(p) p

#   define __PMT(p) p

#  else

#   define __P(p) ()

#   define __PMT(p) ()

#  endif

# endif

#endif /*!__P*/

/* For backward compatibility */

#ifndef _PARAMS

# define _PARAMS(protos) __P(protos)

#endif /*!_PARAMS*/

#ifndef __STDC__

# ifndef const

#  define const

# endif

#endif

#define _IO_UNIFIED_JUMPTABLES 1

#ifndef _G_HAVE_PRINTF_FP

# define _IO_USE_DTOA 1

#endif

#ifndef EOF                    //如果没有定义EOF,则定义它为-1

# define EOF (-1)

#endif

#ifndef NULL

# if defined __GNUG__ && \

(__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))

#  define NULL (__null)

# else

#  if !defined(__cplusplus)         //如果不是C++,则定义为指向0的空指针

#   define NULL ((void*)0)

#  else

#   define NULL (0)                 //如果是c++,则定义NULL为0

#  endif

# endif

#endif

#define _IOS_INPUT 1                //定义一些文件标志宏

#define _IOS_OUTPUT 2

#define _IOS_ATEND 4

#define _IOS_APPEND 8

#define _IOS_TRUNC 16

#define _IOS_NOCREATE 32

#define _IOS_NOREPLACE 64

#define _IOS_BIN 128

/* Magic numbers and bits for the _flags field.              //魔数的一些位为_flag字段.

The magic numbers use the high-order bits of _flags;

the remaining bits are available for variable flags.

Note: The magic numbers must all be negative if stdio     //注意这些魔数必须是相反的,如果stdio仿真是理想的.

emulation is desired. */

#define _IO_MAGIC 0xFBAD0000 /* Magic number */                 /

#define _OLD_STDIO_MAGIC 0xFABC0000 /* Emulate old stdio. */

#define _IO_MAGIC_MASK 0xFFFF0000

#define _IO_USER_BUF 1 /* User owns buffer; don't delete it on close. */

#define _IO_UNBUFFERED 2

#define _IO_NO_READS 4 /* Reading not allowed */

#define _IO_NO_WRITES 8 /* Writing not allowd */

#define _IO_EOF_SEEN 0x10

#define _IO_ERR_SEEN 0x20

#define _IO_DELETE_DONT_CLOSE 0x40 /* Don't call close(_fileno) on cleanup. */

#define _IO_LINKED 0x80 /* Set if linked (using _chain) to streambuf::_list_all.*/

#define _IO_IN_BACKUP 0x100

#define _IO_LINE_BUF 0x200

#define _IO_TIED_PUT_GET 0x400 /* Set if put and get pointer logicly tied. */

#define _IO_CURRENTLY_PUTTING 0x800

#define _IO_IS_APPENDING 0x1000

#define _IO_IS_FILEBUF 0x2000

#define _IO_BAD_SEEN 0x4000

#define _IO_USER_LOCK 0x8000

#define _IO_FLAGS2_MMAP 1

#define _IO_FLAGS2_NOTCANCEL 2

#ifdef _LIBC

# define _IO_FLAGS2_FORTIFY 4

#endif

#define _IO_FLAGS2_USER_WBUF 8

#ifdef _LIBC

# define _IO_FLAGS2_SCANF_STD 16

#endif

/* These are "formatting flags" matching the iostream fmtflags enum values. */

//这些都是“格式式标志”相匹配的iostream fmtflags枚举值。

#define _IO_SKIPWS 01

#define _IO_LEFT 02

#define _IO_RIGHT 04

#define _IO_INTERNAL 010

#define _IO_DEC 020

#define _IO_OCT 040

#define _IO_HEX 0100

#define _IO_SHOWBASE 0200

#define _IO_SHOWPOINT 0400

#define _IO_UPPERCASE 01000

#define _IO_SHOWPOS 02000

#define _IO_SCIENTIFIC 04000

#define _IO_FIXED 010000

#define _IO_UNITBUF 020000

#define _IO_STDIO 040000

#define _IO_DONT_CLOSE 0100000

#define _IO_BOOLALPHA 0200000

struct _IO_jump_t;  struct _IO_FILE;      //两个声明.

/* Handle lock.  */                       //句柄锁

#ifdef _IO_MTSAFE_IO

# if defined __GLIBC__ && __GLIBC__ >= 2

#  include # else

/*# include */

# endif

#else

typedef void _IO_lock_t;   //空类型

#endif

/* A streammarker remembers a position in a buffer. */

//一个streammarker记住一个位置在缓冲器。

struct _IO_marker {

struct _IO_marker *_next;

struct _IO_FILE *_sbuf;

/* If _pos >= 0

it points to _buf->Gbase()+_pos. FIXME comment */

/* if _pos < 0, it points to _buf->eBptr()+_pos. FIXME comment */

int _pos;

#if 0   //下面C++语法不可能执行

void set_streampos(streampos sp) { _spos = sp; }

void set_offset(int offset) { _pos = offset; _spos = (streampos)(-2); }

public:

streammarker(streambuf *sb);

~streammarker();

int saving() { return  _spos == -2; }

int delta(streammarker&);

int delta();

#endif

};

/* This is the structure from the libstdc++ codecvt class.  */  //来自C++库结构的实现

//设计vc的STL库的那位老大P.J.曾经写过这样的一个转换codecvt,来处理wchar,以免写一个wchar就插入一个全0字节

enum __codecvt_result

{

__codecvt_ok,

__codecvt_partial,

__codecvt_error,

__codecvt_noconv

};

#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T

/* The order of the elements in the following struct must match the order

of the virtual functions in the libstdc++ codecvt class.  */

struct _IO_codecvt                 //方法表

{

void (*__codecvt_destr) (struct _IO_codecvt *);

enum __codecvt_result (*__codecvt_do_out) (struct _IO_codecvt *,

__mbstate_t *,

const wchar_t *,

const wchar_t *,

const wchar_t **, char *,

char *, char **);

enum __codecvt_result (*__codecvt_do_unshift) (struct _IO_codecvt *,

__mbstate_t *, char *,

char *, char **);

enum __codecvt_result (*__codecvt_do_in) (struct _IO_codecvt *,

__mbstate_t *,

const char *, const char *,

const char **, wchar_t *,

wchar_t *, wchar_t **);

int (*__codecvt_do_encoding) (struct _IO_codecvt *);

int (*__codecvt_do_always_noconv) (struct _IO_codecvt *);

int (*__codecvt_do_length) (struct _IO_codecvt *, __mbstate_t *,

const char *, const char *, _IO_size_t);

int (*__codecvt_do_max_length) (struct _IO_codecvt *);

_IO_iconv_t __cd_in;

_IO_iconv_t __cd_out;

};

/* Extra data for wide character streams.  */                                        //为宽字节的流定义的额外的数据

struct _IO_wide_data

{

wchar_t *_IO_read_ptr; /* Current read pointer */            //当前读指针

wchar_t *_IO_read_end; /* End of get area. */                //末尾读指针

wchar_t *_IO_read_base; /* Start of putback+get area. */      //开始读的基偏移

wchar_t *_IO_write_base; /* Start of put area. */

wchar_t *_IO_write_ptr; /* Current put pointer. */            //当前写指针

wchar_t *_IO_write_end; /* End of put area. */

wchar_t *_IO_buf_base; /* Start of reserve area. */

wchar_t *_IO_buf_end;  /* End of reserve area. */

/* The following fields are used to support backing up and undo. */

wchar_t *_IO_save_base; /* Pointer to start of non-current get area. */

wchar_t *_IO_backup_base; /* Pointer to first valid character of

backup area */

wchar_t *_IO_save_end; /* Pointer to end of non-current get area. */

__mbstate_t _IO_state;

__mbstate_t _IO_last_state;

struct _IO_codecvt _codecvt;      //实现流的一些转换操作

wchar_t _shortbuf[1];

const struct _IO_jump_t *_wide_vtable;

};

#endif

struct _IO_FILE {                                                                  //传说中的文件流

int _flags;  /* High-order word is _IO_MAGIC; rest is flags. */         //高字是一些魔数,低字是文件标志.

#define _IO_file_flags _flags           //定义可以使用_flags宏

/* The following pointers correspond to the C++ streambuf protocol. */           //下面的指针对应的C + + streambuf协议。

/* 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;             //文件i_node号

#if 0

int _blksize;

#else

int _flags2;            //标志2

#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           //如果使用旧版本_IO_FILE,则就此结束,否则还下文

};

struct _IO_FILE_complete

{

struct _IO_FILE _file;

#endif

#if defined _G_IO_IO_FILE_VERSION && _G_IO_IO_FILE_VERSION == 0x20001

_IO_off64_t _offset;                                                  //如果是新版本则偏移用64位表示

# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T

/* Wide character stream stuff.  */

struct _IO_codecvt *_codecvt;

struct _IO_wide_data *_wide_data; //可见新版本直接处理宽字符流

struct _IO_FILE *_freeres_list;                                       //已经释放的链表

void *_freeres_buf;

size_t _freeres_size;

# else

void *__pad1;

void *__pad2;

void *__pad3;

void *__pad4;

size_t __pad5;

# endif

int _mode;           //文件模式

/* Make sure we don't get into trouble again.  */      //末尾添加足够的位,确保数据安全

char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];

#endif

};

#ifndef __cplusplus                                //如果是c++,同样使用这个结构

typedef struct _IO_FILE _IO_FILE;

#endif

struct _IO_FILE_plus;

extern struct _IO_FILE_plus _IO_2_1_stdin_;      //定义三个导出变量,三个流文件,可以看下面的_IO_FILE_plus

extern struct _IO_FILE_plus _IO_2_1_stdout_;

extern struct _IO_FILE_plus _IO_2_1_stderr_;

#ifndef _LIBC                                       //如果是LIBC,则定义_IO_stdin等三个变量

#define _IO_stdin ((_IO_FILE*)(&_IO_2_1_stdin_))

#define _IO_stdout ((_IO_FILE*)(&_IO_2_1_stdout_))

#define _IO_stderr ((_IO_FILE*)(&_IO_2_1_stderr_))

#else

extern _IO_FILE *_IO_stdin attribute_hidden;       //如果定义则隐藏_IO_stdin,等三个变量

extern _IO_FILE *_IO_stdout attribute_hidden;

extern _IO_FILE *_IO_stderr attribute_hidden;

#endif

/* Functions to do I/O and file management for a stream.  */     //下面是的流管理功能

/* Read NBYTES bytes from COOKIE into a buffer pointed to by BUF. //读cookie

Return number of bytes read.  */

/ *读取NBYTES字节来自Cookie从一个缓冲区指针到BUF。

返回读到字节数。 * /

typedef __ssize_t __io_read_fn (void *__cookie, char *__buf, size_t __nbytes); //定义一个函数,并不是函数指针

/* Write N bytes pointed to by BUF to COOKIE.  Write all N bytes

unless there is an error.  Return number of bytes written, or -1 if

there is an error without writing anything.  If the file has been

opened for append (__mode.__append set), then set the file pointer

to the end of the file and then do the write; if not, just write at

the current file pointer.  */

/ *写N字节指出了从缓冲区到COOKIE里。写所有N字节

除非有一个错误。返回的已经写入字节数,或-1如果

那里有一个错误没有写入东西。如果该文件打开以APPEND方式( __mode设置__append) ,然后设置文件指针

到该文件最后,然后写;如果没有,只写在

当前的文件指针。 * /

typedef __ssize_t __io_write_fn (void *__cookie, __const char *__buf,  //写cookie

size_t __n);

/* Move COOKIE's file position to *POS bytes from the

beginning of the file (if W is SEEK_SET),

the current position (if W is SEEK_CUR),

or the end of the file (if W is SEEK_END).

Set *POS to the new file position.

Returns zero if successful, nonzero if not.  */

移动COOKIE的文件的位置到* POS处,从

开始的文件(如果W是SEEK_SET ) ,

当前的位置(如果W是SEEK_CUR ) ,

或文件的末尾(如果W是SEEK_END ) 。

设置* POS到新文件的位置。

返回零如果成功的话,如果不是非零。*/

typedef int __io_seek_fn (void *__cookie, _IO_off64_t *__pos, int __w);//定位COOKIE

/* Close COOKIE.  */

typedef int __io_close_fn (void *__cookie);//关闭COOKIE

#ifdef _GNU_SOURCE      //如果是GNU源代码,就定义下面变量,显然,我们是GNU源代码

/* User-visible names for the above.  */

typedef __io_read_fn cookie_read_function_t;

typedef __io_write_fn cookie_write_function_t;

typedef __io_seek_fn cookie_seek_function_t;

typedef __io_close_fn cookie_close_function_t;

/* The structure with the cookie function pointers.  */

typedef struct

{

__io_read_fn *read;  /* Read bytes.  */

__io_write_fn *write;  /* Write bytes.  */

__io_seek_fn *seek;  /* Seek/tell file position.  */

__io_close_fn *close;  /* Close file.  */

} _IO_cookie_io_functions_t;

typedef _IO_cookie_io_functions_t cookie_io_functions_t;

struct _IO_cookie_file;

/* Initialize one of those.  */        //初始化上面变量

extern void _IO_cookie_init (struct _IO_cookie_file *__cfile, int __read_write,

void *__cookie, _IO_cookie_io_functions_t __fns);

#endif

#ifdef __cplusplus   //如果是c++

extern "C" {

#endif

extern int __underflow (_IO_FILE *);        //下溢

extern int __uflow (_IO_FILE *);             //溢出

extern int __overflow (_IO_FILE *, int);        //上溢

#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T   //如果是wchar版本,新版本

extern _IO_wint_t __wunderflow (_IO_FILE *);

extern _IO_wint_t __wuflow (_IO_FILE *);

extern _IO_wint_t __woverflow (_IO_FILE *, _IO_wint_t);

#endif

#if  __GNUC__ >= 3

# define _IO_BE(expr, res) __builtin_expect ((expr), res)

#else

# define _IO_BE(expr, res) (expr)

#endif

//以下这些定义十分的重要,标准库很多复杂功能都是来自于下面宏.

//下面每个宏几乎是一个函数,libio里文件大都在这些基础上实现

#define _IO_getc_unlocked(_fp) \

(_IO_BE ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end, 0) \           //比较当前读指针,大于等末读指针尾溢出,返回新的指针,具体看下篇

? __uflow (_fp) : *(unsigned char *) (_fp)->_IO_read_ptr++)

#define _IO_peekc_unlocked(_fp) \                                 //同上,但判断还加上是否文件尾

(_IO_BE ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end, 0) \

&& __underflow (_fp) == EOF ? EOF \

: *(unsigned char *) (_fp)->_IO_read_ptr)

#define _IO_putc_unlocked(_ch, _fp) \                              //将写ch,写到fp里,并返回当前

(_IO_BE ((_fp)->_IO_write_ptr >= (_fp)->_IO_write_end, 0) \

? __overflow (_fp, (unsigned char) (_ch)) \

: (unsigned char) (*(_fp)->_IO_write_ptr++ = (_ch)))

#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T

# define _IO_getwc_unlocked(_fp) \                      //宽字节,具体实现同上

(_IO_BE ((_fp)->_wide_data->_IO_read_ptr >= (_fp)->_wide_data->_IO_read_end,\

0) \

? __wuflow (_fp) : (_IO_wint_t) *(_fp)->_wide_data->_IO_read_ptr++)

# define _IO_putwc_unlocked(_wch, _fp) \

(_IO_BE ((_fp)->_wide_data->_IO_write_ptr \

>= (_fp)->_wide_data->_IO_write_end, 0) \

? __woverflow (_fp, _wch) \

: (_IO_wint_t) (*(_fp)->_wide_data->_IO_write_ptr++ = (_wch)))

#endif

#define _IO_feof_unlocked(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0)      //是否文件结束

#define _IO_ferror_unlocked(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0)    //判断标志,是否出错

extern int _IO_getc (_IO_FILE *__fp);                 //在libio实现,看下篇

extern int _IO_putc (int __c, _IO_FILE *__fp);

extern int _IO_feof (_IO_FILE *__fp) __THROW;

extern int _IO_ferror (_IO_FILE *__fp) __THROW;

extern int _IO_peekc_locked (_IO_FILE *__fp);

/* This one is for Emacs. */

#define _IO_PENDING_OUTPUT_COUNT(_fp) \

((_fp)->_IO_write_ptr - (_fp)->_IO_write_base)

extern void _IO_flockfile (_IO_FILE *) __THROW;

extern void _IO_funlockfile (_IO_FILE *) __THROW;

extern int _IO_ftrylockfile (_IO_FILE *) __THROW;

#ifdef _IO_MTSAFE_IO

# define _IO_peekc(_fp) _IO_peekc_locked (_fp)

# define _IO_flockfile(_fp) \

if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_flockfile (_fp)

# define _IO_funlockfile(_fp) \

if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_funlockfile (_fp)

#else

# define _IO_peekc(_fp) _IO_peekc_unlocked (_fp)

# define _IO_flockfile(_fp) /**/

# define _IO_funlockfile(_fp) /**/

# define _IO_ftrylockfile(_fp) /**/

# define _IO_cleanup_region_start(_fct, _fp) /**/

# define _IO_cleanup_region_end(_Doit) /**/

#endif /* !_IO_MTSAFE_IO */

//当然这些函数也来自于libio目录下的其他文件

extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict,

_IO_va_list, int *__restrict);

extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict,

_IO_va_list);

extern _IO_ssize_t _IO_padn (_IO_FILE *, int, _IO_ssize_t);

extern _IO_size_t _IO_sgetn (_IO_FILE *, void *, _IO_size_t);

extern _IO_off64_t _IO_seekoff (_IO_FILE *, _IO_off64_t, int, int);

extern _IO_off64_t _IO_seekpos (_IO_FILE *, _IO_off64_t, int);

extern void _IO_free_backup_area (_IO_FILE *) __THROW;

#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T

extern _IO_wint_t _IO_getwc (_IO_FILE *__fp);

extern _IO_wint_t _IO_putwc (wchar_t __wc, _IO_FILE *__fp);

extern int _IO_fwide (_IO_FILE *__fp, int __mode) __THROW;        ///看上面fwide函数

# if __GNUC__ >= 2

/* While compiling glibc we have to handle compatibility with very old

versions.  */

#  if defined _LIBC && defined SHARED

#   include #   if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)

#    define _IO_fwide_maybe_incompatible \         //是否是宽字节的,fwide用到它

(__builtin_expect (&_IO_stdin_used == NULL, 0))

extern const int _IO_stdin_used;

weak_extern (_IO_stdin_used);

#   endif

#  endif

#  ifndef _IO_fwide_maybe_incompatible

#   define _IO_fwide_maybe_incompatible (0)

#  endif

/* A special optimized version of the function above.  It optimizes the

case of initializing an unoriented byte stream.  */

#  define _IO_fwide(__fp, __mode) \        //改变流模式这里已经实现了

({ int __result = (__mode);            \

if (__result < 0 && ! _IO_fwide_maybe_incompatible)        \

{              \

if ((__fp)->_mode == 0)           \

/* We know that all we have to do is to set the flag.  */       \

(__fp)->_mode = -1;            \

__result = (__fp)->_mode;           \

}              \

else if (__builtin_constant_p (__mode) && (__mode) == 0)        \

__result = _IO_fwide_maybe_incompatible ? -1 : (__fp)->_mode;       \

else              \

__result = _IO_fwide (__fp, __result);          \

__result; })

# endif

extern int _IO_vfwscanf (_IO_FILE * __restrict, const wchar_t * __restrict,

_IO_va_list, int *__restrict);

extern int _IO_vfwprintf (_IO_FILE *__restrict, const wchar_t *__restrict,

_IO_va_list);

extern _IO_ssize_t _IO_wpadn (_IO_FILE *, wint_t, _IO_ssize_t);

extern void _IO_free_wbackup_area (_IO_FILE *) __THROW;

#endif

#ifdef __LDBL_COMPAT

# include #endif

#ifdef __cplusplus

}

#endif

#endif /* _IO_STDIO_H */

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值