标准I/O库学习笔记

来源:互联网 发布:ajax代码实例 java 编辑:程序博客网 时间:2024/05/16 18:12
 

                                                 .标准I/O学习笔记

                                                                                                                     -----------201216  by  ppeng

1.一些常见的问题

   通过仔细阅读《UNIX环境高级编程》,理清了一些以前不懂关于I/O方面的问题,

下面作简单的总结。

1.1 标准I/O库与文件I/O函数有什么区别

      很明显的两种,本人菜鸟,其他的没发现....

Diff 1

      文件I / O函数——打开文件、读文件、写文件等等。大多数UNIX文件I / O只需用到5个函数:open、read、write、lseek 以及close。每个read和write都调用内核中的一个系统调用。这些不带缓存的I / O函数不是ANSI C的组成部分。

      标准I / O库处理很多细节,例如缓存分配,以优化长度执行I / O等。这样使用户不必担心如何选择使用正确的块长度。标准I / O库是在系统调用函数基础上构造的,它便于用户使用,但是如果不较深入地了解库的操作,也会带来一些问题。

Diff 2

      文件I / O函数都是针对文件描述符的。当打开一个文件时,即返回一个文件描述符,然后该文件描述符就用于后读的I / O操作。

      标准I / O库,它们的操作则是围绕流(stream)进行的,当用标准I / O库打开或创建一个文件时,我们已使一个流与一个文件相结合。当打开一个流时,标准I / O函数fopen返回一个指向FILE对象的指针。该对象通常是一个结构,它包含了I / O库为管理该流所需要的所有信息:用于实际I / O的文件描述符,指向流缓存的指针,缓存的长度,当前在缓存中的字符数,出错标志等等。

1.2 stdin , stdout和stderr到底是什么东西

      上面说了,文件I/O函数打开一个文件时,会返回一个文件描述符。标准输入、标准输出和标准出错说白了也是3个文件(个人理解,不一定对),我们用文件描述符STDINFILENO , STDOUTFILENO和STDERRFILENO分别表示它们,而标准I/O库不是围绕流(stream)进行的么?当打开一个流时,标准I / O函数fopen返回一个指向FILE对象的指针,

这就是3个FILE对象的指针嘛!想操作标准输入、标准输出和标准出错的话就用这3个指针了。

1.3 有哪些常用的I/O函数

1.3.1 输入函数

一次读一个字符:

int getc(FILE *f p) ;

int fgetc(FILE *f p) ;

int getchar(void);

一次读一行:

char *fgets(char *buf, int n,FILE * f p) ;

char *gets(char *buf) ;

从文件中读数据,我就只用fgetc和fgets,其他的不用,这两个函数有输入参数fp,我们就既可以从文件中读,也可以标准输入。标准输入的话,传stdinstdout就行了。写和输出是一个道理了。

1.3.2 输出函数

一次写一个字符:

int putc(int c, FILE *f p ) ;

int fputc(int c, FILE *f p);

int putchar(int c) ;

一次写一行:

int fputs(const char *str, FILE *f p) ;

int puts(const char *str) ;

也只用fputc和fputs就行了,其他的不用。

1.3.3 判断出错和判断文件尾端函数(知道为什么要这两个函数吗)

int ferror(FILE *f p) ;

int feof(FILE *f p) ;

两个函数返回:若条件为真则为非0(真),否则为0(假)

void clearerr(FILE *f p) ;

在大多数实现的FILE对象中,为每个流保持了两个标志:

•出错标志。

•文件结束标志。

调用clearerr则清除这两个标志。

为什么要这两个函数呢?

当你使用fgetc函数时,不管是出错还是已经读到文件结尾,函数都会返回EOF,在stdio.h中定义为-1,这样你就不知道到底是出错还是读完了,有了这两个函数,就可以轻易的判断出。同样,当你使用fgets时,不管是出错还是已经读到文件结尾,函数都会返回NULL

1.3.3 二进制I / O函数

     上述的函数以一次一个字符或一次一行的方式进行操作。如果为二进制I / O,那么我们更愿意一次读或写整个结构。为了使用fgetc或fputc做到这一点,必须循环通过整个结构,一次读或写一个字节。因为fputs在遇到null字节时就停止,而在结构中可能含有null字节,所以不能使用每次一行函数实现这种要求。相类似,如果输入数据中包含有null字节或新行符,则fgets也不能正确工作。因此,提供了下列两个函数以执行二进制I / O操作

      size_t fread(void *p t r, size_ts i z e, size_tn o b j, FILE *f p) ;

      size_t fwrite(const void *p t r, size_t s i z e, size_tn o b j, FILE *f p) ;

      两个函数的返回:读或写的对象数

这些函数有两个常见的用法:

(1) 读或写一个二进制数组。例如,将一个浮点数组的第2至第5个元素写至一个文件上,

可以写作:

      float  data[10];

      FILE *fp = fopen("c:\\a.txt","r+");

      if( fwrite(&data[2],sizeof(float),4,fp) != 4 )

           ...报错...

(2) 读或写一个结构。例如,可以写作:

       struct {

short count;

long total;

char name[512];

} item;

if (fwrite(&item, sizeof(item), 1, fp) != 1)

                    ...报错...

1.3.4 格式化I / O输入输出函数

int printf(const char *format, ...);

int fprintf(FILE *fp, const char * format, ...);

两个函数返回:若成功则为输出字符数,若输出出错则为负值

int sprintf(char *buf, const char * format, ...);

应用实例

1.用fgetc和fputc将标准输入复制到标准输出

  

int main(void)

{

    int count = 0;

While( ( count = fgetc( stdin ) )  !=  EOF )     //出错或者读到结尾则退出

{

    If( fputc( count, stdout ) == EOF )

        .....报错.... 

}

//结束的原因是出错还是读到结尾?

If( ferror( stdin ) )

       ....报错.... 

exit(0);

}

2.用fgets和fputs将标准输入复制到标准输出

int main(void)

{  

Char buf[1024];  

While( fgets( buf , 1024, stdin )  !=  NULL)     //出错或者读到结尾则退出

{

    If( fputs( buf , stdout ) == EOF )

        .....报错.... 

}

//结束的原因是出错还是读到结尾?

If( ferror( stdin ) )

       ....报错.... 

exit(0);

}

如果不是标准输出和输入,可以先fopen打开一个文件,在用同样的方法使用这个返回的FILE类型的指针。

FILE *fp = fopen("c:\\a.txt","r+");

原创粉丝点击