坐牢第十七天 20240726(IO)

一.笔记

一、IO基础

1> IO:(inout output) 所谓IO,就是程序与外部设备进行信息交换的过程

2> IO的分类:标准IO和文件IO

3> 标准IO:调用封装好的相关库函数,来实现数据的输入输出

4> 文件IO:调用系统(内核)提供的相关函数,来实现数据的输入输出

5> 标准IO和文件IO的区别:

标准I文件IO
属于库函数系统调用
操作对象文件指针文件描述符
有无缓冲区

6>阻塞IO和非阻塞IO

7> 目前所接触过的IO函数:

printf、scanf、putchar、getchar、puts、gets

8> 常用的IO接口函数

标准IO:fprint、fscanf、fputc、fgetc、fputs、fgets、fread、 fwrite、fopen、fclose、fseek、ftell、rewind。。。

文件IO:open、close、read、write、seek。。。

9> IO操作流程

二、标准IO

2.1 标准IO提供的内容

可以通过指令:man 7 stdio.h 可以查看该头文件提供的内容

Plain Text
自动换行
1、标准的缓冲输入输出

2、提供的数据类型    

 FILE          文件结构体类型

off_t         偏移量类型

size_t        大小的类型,一般是一个long int类型

3、提供的偏移量的宏值

 SEEK_SET:文件起始位置        

SEEK_END:文件结束位置        

SEEK_CUR:文件当前位置

4、提供文件结束标志:

EOF (end of file)

5、默认提供的文件指针:      

 stdin:标准输入指针    

 stdout:标准输出指针        

stderr:标准出错指针

6、标准IO会提供三种缓冲区:

  全缓存        行缓存        不缓存          

2.2FILE结构体

1> 如何追该结构体:可以使用 vi -t FILE

2> 结构体解析

struct _IO_FILE {
char* _IO_buf_base;   /* 缓冲区开始地址 */
char* _IO_buf_end;    /* 缓冲区结束地址 */

 int _fileno;         //用于系统调用的文件描述符
 };  

3> 当一个程序启动后,系统会自动打开三个文件指针:

stdin:标准输入文件指针 ---> scanf、getchar、gets

stdout:标准输出文件指针 ----> printf、putchar、puts

stderr:标准出错文件指针 ---> perror

以上三个文件指针,都是针对于终端文件操作而言的

2.3 fopen 打开文件

 #include <stdio.h>

 FILE *fopen(const char *pathname, const char *mode);
功能:以指定的方式打开一个给定的文件,并返回该文件的文件地址    

参数1:要打开的文件文件路径,可以是相对路径,也可以是绝对路径    

参数2:文件打开的方式,需要以以下字符开头的字符串  

r     以只读的形式打开文件,文件光标定位在开头.如果文件不存在,则报错

r+     以读写的形式打开文件,文件光标定位在开头.如果文件不存在,则报错
w      以只写的形式打开文件,如果文件存在,则清空文件内容,如果文件不存在,则创建该文件,文件光标定位在开头.
w+     以读写的形式打开文件,如果文件存在,则清空文件内容,如果文件不存在,则创建该文件,文件光标定位在开头.
a      以追加的形式打开文件,如果文件不存在则创建文件,文件光标定位在结尾
a+     以读或者追加的形式打开文件,如果文件不存在,则创建文件,如果第一次是读数据,则光标定位在开头,否则定位在结尾
返回值:成功调用返回打开的文件地址,失败返回NULL,并置位错误码

2.4 fclose:关闭文件

 #include <stdio.h>
int fclose(FILE *stream);
 功能:关闭给定的文件指针    

参数1:要关闭的文件指针    

返回值:成功返回0,失败返回EOF,并置位错误码

2.5 fgetc\fputc:单字符的输入输出

  #include <stdio.h>
   int fputc(int c, FILE *stream);
   功能:将给定的字符,写入到文件指针stream指向的文件中去    

参数1:要写入的字符    

参数2:打开的文件指针    

返回值:成功返回写入字符的ascii值,失败返回EOF,并置位错误码              

#include <stdio.h>
int fgetc(FILE *stream);      

功能:从指定文件中,读取一个字符      

参数:打开的文件指针      

返回值:从文件中读取的第一个字符的ascii值,失败返回EOF并置位错误码 

2.6 有关错误码问题

1> 错误码是调用内核提供的函数时,如果调用出错,那么内核空间会向用户空间反馈一个错误信息

2> 错误信息千奇百怪,并且是字符串内容,为了方便起见,给这些错误信息,进行编号

3> 如果,内核空间函数调用出问题时,只需要反馈错误编号即可,这个错误编号就叫做错误码

4> 常见错误码:可以通过指令 vi -t EIO 查看

2.7 fputs\fgets:字符串输入输出

 #include <stdio.h>

int fputs(const char *s, FILE *stream);
 功能:将给定的字符串,写入到文件中    

参数1:要写入的字符串起始地址    

参数2:打开的文件指针    

返回值:成功返回写入的字符个数(字符串长度),失败返回EOF        

 #include <stdio.h>

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

功能:从stream所指向的文件中,最多读取size-1的字符到s中,在读取过程中,如果遇到回车或者文件结束,会结束本次读取,并且会把回车也放入容器中。在后面自动加上'\0'      

参数1:存放数据的容器,一般是一个字符数组      

参数2:读取的大小      

参数3:文件指针      

返回值:成功返回容器的起始地址,失败返回NULL

2.8 关于缓冲区

1> 标准IO提供了三种缓冲区:行缓存、全缓存、不缓存

2> 行缓存:有关标准输入、标准输出指针对应的缓冲区,其大小位1024字节

3> 全缓存:有关普通文件指针对应的缓冲区,其大小位4096字节

4> 不缓存:有关标准出错文件指针对应的缓冲区,其大小位 0

5> 行缓存的刷新时机

1.换行会刷新行缓存

2.程序结束后,会自动刷新行缓存

3.当文件指针关闭后,会刷新行缓存

4.当使用fflush函数刷新文件指针时,会刷新行缓存

5.当输入输出切换时,会刷新行缓存

6.当缓存区满了后,再放数据时,会刷新行缓存

6> 全缓存的刷新时机

1.程序结束后,会自动刷新全缓存

2.当文件指针关闭后,会刷新全缓存

3.当使用fflush函数刷新文件指针时,会刷新全缓存

4.当输入输出切换时,会刷新全缓存

5.当缓存区满了后,再放数据时,会刷新全缓存

二.作业

1> 使用fgets统计给定文件的行号

#include <myhead.h>
int main(int argc, char const *argv[])
{
   if (argc!=2)
   {
      printf("input file error!!!\n");
      printf("usage:./a.out filename\n");
      return -1;
   }
      FILE * fp=NULL;
    if ((fp=fopen(argv[1],"r"))==NULL)
    {
       printf("fopen error\n");
       return -1;
    }
    char buf[128]="";
    int count=0;
    while (1)
    {
        bzero(buf,sizeof(buf));
        if(fgets(buf,strlen(buf)-1,fp)==NULL)
        {
            count++;
        }
        if (fgets(buf,sizeof(buf),fp)==NULL)
        {
            break;//说明文件读取结束
        }
    }
    printf("该文件一共有%d行\n",count);
    fclose(fp);
    return 0;
}

2> 使用fgets、fputs完成两个文件的拷贝

#include <myhead.h>
int main(int argc, char const *argv[])
{
    if (argc!=3)
   {
      printf("input file error!!!\n");
      printf("usage:./a.out filename\n");
      return -1;
   }
    FILE*fp1=NULL;
    FILE*fp2=NULL;
    if (NULL==(fp1=fopen(argv[1],"r"))||NULL==(fp2=fopen(argv[2],"w")))
    {
      printf("拷贝失败\n");
      return -1;
    }
    char buf[128]="";
    while (1)
    {
        bzero(buf,sizeof(buf));
        fgets(buf,strlen(buf),fp1);
        if (fgets(buf,sizeof(buf),fp1)==NULL)
        {
            break;//说明文件读取结束
        }
        fputs(buf,fp2);
    } 
    fclose(fp1);
    fclose(fp2);
    printf("拷贝成功\n");
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值