linux 标准I/O函数详解

1、I/O操作是系统的基础。

I/O 表示的input【输入】和output【输出】 。I/O操作是系统实现的基础。如果没有I/O操作,所以有的系统文件将无法存储,更谈不上处理与分析,系统运行的结果也不为用户所见。


2、系统IO与标准IO的区别

I/O 分为标准IO 和系统IO 。标准io称为stdio,系统IO又称为文件IO。系统IO是内核提供给用户处理IO操作的接口。例如:标准C是不能处理输入输出问题的。必须借助于内核提供的接口实现对program的输入输出处理。标准I/O 是在系统IO的基础上进行的二次封装。以屏蔽不同体系结构之间的差异,增加程序的可移植性。

从上图可以发现:标准I/O是基于系统IO实现的。fopen是基于open方法实现,fclose是基于close实现的。fgetc,fputc,fgets,fputs,fread,fwrite,是基于read和write方法是实现,fseek,ftell,rewind是基于lseek方法实现。

贯穿标准IO的全过程,有一个重要的结构体:FILE,贯穿系统IO的全过程,有一个重要的整形变量:int fd(其中fd表示:file descriptot,文件描述符)。二者的关系如何?

3、标准I/O相关函数使用:

3.1 fopen函数:

用法:FILE *fopen(const char *path, const char *mode);

参数:const  char *path 打开指定路径下的文件。const修饰为了增强程序安全性【调用的参数不能修改】 const char *mode 表示文件的打开方式:

mode 含义
r 只读方式打开,文件位置指针位于文件的起始处【文件必须事先存在,否则出错】
r+ 只读写方式打开,文件位置指针位于文件的起始处【文件必须事先存在,否则出错】
w 有则清空,无则创建。文件位置指针位于文件的起始处
w+ 有则清空,无则创建。文件位置指针位于文件的起始处
a 以附加的方式打开,文件位置指针位于未见末尾处
a+ 以读或附加的方式打开,文件位置指针取决于用户的操作方式。读则在起始处,附加则在末尾处。

返回值:打开成功则返回FILE 类型指针,失败则返回空指针,并写入errno值。

用法举例:

    #include <stdio.h>    
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    int main ()
    {
    FILE *f = NULL;
    f = fopen("tmp","w");
    if(f == NULL)
    {
    //fprintf(stderr,"fopen() failed ! errno = %d\n",errno);
    //查看出错原因。去:/usr/include/asm-generic/errno-bash.h
    //使用perro函数
    //perror("fopen()");
    //另外一个好用的函数
    fprintf(stderr,"fopen():%s\n",strerror(errno));
    exit(1);
    }
    puts("ok");
    fclose(f);
    //exit(0);
    }

3.2 fclose:

功能:关闭打开的文件指针,并且刷新缓存。

用法:int fclose(FILE *fp);

参数:FILE *fp 打开的文件指针。

返回值:成功返回0,如果不成功返回EOF,并且设置errno。

3.3、fgetc fputc

功能:

fgetc:从流中读入下一个字符,【字符读入以整形返回】。

fputc:输出一个字符

用法:

int fgetc(FILE *stream);

int fputc(int c, FILE *stream);

返回值:

fgetc(),  getc() and getchar() return the character read as an unsigned char cast to an

int or EOF on end of file or error.

fputc(),  putc() and putchar() return the character written as an unsigned char cast to

an int or EOF on error

注意点:fgetc的返回值要用一个int接收,不能定义为char型。

EOF是 End Of File 的缩写。在C语言中,它是在标准库中定义的一个宏。多数人认为文件中有一个EOF,用于表示文件的结尾。但这个观点实际上是错误的,在文件所包含的数据中,并没有什么文件结束符。对getc 而言,如果不能从文件中读取,则返回一个整数-1,这就是所谓的EOF。返回 EOF 无非是出现了两种情况,一是文件已经读完;;二是文件读取出错,反正是读不下去了。

用法举例:用fgetc 和fputc实现文件复制的功能。

#include <stdio.h>

#include <stdlib.h>

int main (int argc ,char *argv[])

{

FILE *fs,*fd;

int ch;

if(argc < 3)

{

fprintf(stderr,"useage:%s<src_filename des_filename>",argv[0]);

exit(1);

}

fs = fopen(argv[1],"r");

if(fs == NULL)

{

perror("fopen()");

exit(1);

}

fd = fopen(argv[2],"w");

if(fd == NULL)

{

fclose(fs);          //如果此时程序中断,应该释放打开源

perror("fopen()");

exit(1);

}

while(1)

{

ch = fgetc(fs);

if(ch == EOF)

{

break;

}

fputc(ch,fd);

}

fclose(fd);

fclose(fs);

3.3、fputs 和fgets

功能:以字符串的形式读取和写入文件。

用法:

char *fgets(char *s, int size, FILE *stream);

int fputs(const char *s, FILE *stream);

返回值:fgets会把从*stream中读取的size个字节放入到*s,char* 表示回写。fputs 返回值是一个整形,成功为非负值,失败,返回EOF

用法举例:用fgets和fputs实现文件复制的功能。

#include <stdio.h>

#include <stdlib.h>

#define BUFSIZE 1024

int main (int argc ,char **argv)

{

if(argc < 2)

{

fprintf(stderr,"Usage....\n");

exit(1);

}

char buf[BUFSIZE];

FILE *fsp,*fdp;

fsp = fopen(argv[1],"r");

if(fsp == NULL)

{

perror("fopen()");

exit(1);

}

fdp = fopen(argv[2],"w");

if(fdp == NULL)

{

fclose(fsp);

perror("fopen()");

exit(1);

}

while(fgets(buf,BUFSIZE,fsp) != NULL)

{

fputs(buf,fdp);

}

exit(0);

}

3.4 fread 和 fwrite

作用:二进制流的输入输出

用法:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

注意:size是每一个块的大小,nmemb是块的个数。

返回值:读取或写入的字节个数【正确】。读完或出错返回0值

用法举例:用fread和fwrite实现文件复制的功能。

1 #include <stdio.h>

2 #include <stdlib.h>

3 #define BUFSIZE 1024

4 int main (int argc ,char **argv)

5 {

6

7     if(argc < 3)

8     {

9         fprintf(stderr,"Usage....\n");

10         exit(1);

11     }

12     FILE *fsp,*fdp;

13     char buf[BUFSIZE];

14     int n,res;

15     fsp = fopen(argv[1], "r");

16     if(fsp == NULL)

17     {

18         perror("fopen()");

19         exit(1);

20     }

21     fdp = fopen(argv[2],"w");

22     if(fdp == NULL)

23     {

24         fclose(fsp);

25         perror("fopen()");

26         exit(1);

27     }

28     while ((n = fread(buf,1,BUFSIZE,fsp)) > 0 )

29     {

30         res = fwrite(buf,1,n,fdp);

31         n = n - res;                            //全部读取

32         if(n > 0)

33         {

34             while(res > 0)

35             {

36                 res = fwrite(buf,1,n,fdp);

37                 n = n -res;

38             }

39         }

40     }

41     exit(0);

42 }

时间: 2024-12-16 01:18:03

linux 标准I/O函数详解的相关文章

c/c++ 标准库 bind 函数 详解

标准库 bind 函数 详解 bind函数:接收一个函数名作为参数,生成一个新的函数. auto newCallable = bind(callbale, arg_list); arg_list中的参数可能包含入_1, _2等,这些是新函数newCallable的参数. 在这篇博客lambda 表达式 介绍 中,讨论了find_if的第三个参数的问题,当时是用lambda表达式解决的,有了bind函数后,也可以用bind函数解决. 解决办法:bind(check_size, _1, sz) au

Linux操作系统shell与函数详解

shell和函数的定义 1. linux  shell 函数 将一组命令集或语句形成一个可用的块, 这些语句块称为函数. 2. shell  函数的组成 函数名:函数名字,注意一个脚本中函数名要唯一,否则会引起调用函数紊乱. 函数体: 函数内部命令的集合,实现一个业务的功能. 3. shell  函数定义的格式 function  函数名()   # function可以省略,注意()内部不带任何参数. { 命令1 命令2 . . . } 函数使用方法举例 1.函数定义及引用实例一: 最简单的定

Linux内核中kzalloc函数详解

***************************************************************************************************************************作者:EasyWave                                                                                 时间:2013.02.06 类别:Linux 内核驱动源码分析    

(笔记)Linux下的ioctl()函数详解

我这里说的ioctl函数是指驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围.写这篇文章是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. 一. 什么是ioctl      ioctl是设备驱动程序中对设备的I/O通道进行管理的函数.所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率.马达的转速等等.它的调用个数如下:  int ioctl(int fd, ind cmd, …):      其中fd是用户程序

Linux下的ioctl()函数详解

我这里说的ioctl函数是指驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围.写这篇文章是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. 一. 什么是ioctl     ioctl是设备驱动程序中对设备的I/O通道进行管理的函数.所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率.马达的转速等等.它的调用个数如下: int ioctl(int fd, ind cmd, -):     其中fd是用户程序打开设

Linux系统编程——vfork() 函数详解

所需头文件: #include <sys/types.h> #include <unistd.h> pid_t vfork(void); 功能: vfork() 函数和 fork() 函数(fork()如何使用,请点此链接)一样都是在已有的进程中创建一个新的进程,但它们创建的子进程是有区别的. 参数: 无 返回值: 成功:子进程中返回 0,父进程中返回子进程 ID.pid_t,为无符号整型. 失败:返回 -1. fork() 与 vfock() 都是创建一个进程,那它们有什么区别呢

Linux popen()函数详解

表头文件 #include<stdio.h> 定义函数 FILE * popen( const char * command,const char * type); 函数说明 popen()会调用fork()产生子进程,然后从子进程中调用/bin/sh -c来执行参数command的指令.参数type可使用“r”代表读取,“w”代表写入.依照此type值,popen()会建立管道连到子进程的标准输出设备或标准输入设备,然后返回一个文件指针.随后进程便可利用此文件指针来读取子进程的输出设备或是写

linux Socket send与recv函数详解

转自:http://www.cnblogs.com/blankqdb/archive/2012/08/30/2663859.html linux send与recv函数详解 1 #include <sys/socket.h> 2 ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags); 3 ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags)

linux网络编程之shutdown() 与 close()函数详解

linux网络编程之shutdown() 与 close()函数详解 参考TCPIP网络编程和UNP: shutdown函数不能关闭套接字,只能关闭输入和输出流,然后发送EOF,假设套接字为A,那么这个函数会关闭所有和A相关的套接字,包括复制的:而close能直接关闭套接字. 1.close()函数 [cpp] view plain copy print? <span style="font-size:13px;">#include<unistd.h> int