IO进程-标准IO

目录

概念

特点

缓冲区

全缓冲:与文件有关

行缓冲:与终端相关

不刷新

函数

打开文件

fopen

feropen

打印错误信息perror

关闭文件

close

读写操作

fgetc(读取单个字符)

fputc(写入单个字符)

fgets(读取一行)

fputs(写入一行)

二进制读写

fread

fwrite

判断是否到文件结尾

feof

判断文件是否出错

ferror

定位操作

rewind

fseek

ftell

对比命令

diff


概念

在c库(c语言函数库)中定义的一组用于输入输出的函数(接口)。

特点

  1. 通过缓冲机制减少系统调用,提高效率,需要刷新数据,如果没有刷新,掉电数据丢失,可以通过超电容(硬件,检测掉电后通过供电保存数据)和文件的双备份操作(软件,crc校验,一次写两个文件,读的时候只读一个文件)
  2. 围绕流进行操作,流用FILE *表示
  3. 标准IO默认打开三个流,stdin(标准输入),stdout(标准输出),标准错误(stderr)
  4. 只能操作普通文件

注意:

ctags索引的使用:

  1. vi-t 要查找的内容(查找宏,数据类型等)        输入前面序号,回车
  2. 继续追踪:将光标定位到要追踪的内容上,ctrl + ]        回退: ctrl + t

缓冲区

全缓冲:与文件有关

刷新条件:

  1. 程序正常退出
  2. 缓冲区满刷新(不正常退出时要缓冲区满才能刷新)
  3. 强制刷新fflush

行缓冲:与终端相关

刷新条件:

  1. \n:功能:1. 换行 2. 刷新缓冲区(将缓冲区的内容从缓冲区输出)
  2. 程序退出:正常结束时,需要调用一下printf才能计算大小(用最后的位置 - 最初的位置,end - base)
  3. 缓冲区满刷新(不正常退出时,例如死循环)
  4. 强制刷新:fflush

不刷新

没有缓冲区,标准错误

函数

打开文件

fopen

FILE *fopen(const char *path, const char *mode)
功能:打开文件
参数:
    path:打开的文件
    mode:打开的方式
        r/rb:只读,当文件不存在时报错,文件流定位到文件开头
        r+/r+b:可读可写,当文件不存在时报错,文件流定位到文件开头
        w/wb:只写,文件不存在创建,存在清空
        w+/w+b:可读可写,文件不存在创建,存在清空
        a/ab:追加(在末尾写),文件不存在创建,存在追加,文件流定位到文件末尾
        a+/a+b:读和追加,文件不存在创建,存在追加,读文件流定位到文件开头,写文件流定位到文件末尾
            注:当a的方式打开文件时,写只能在末尾进行追加,定位操作是无法改变写的位置,但是可以改变读的位置
返回值:
    成功:文件流
    失败:NULL,并且会设置错误码
#include 

int main(int argc, char const *argv[])
{
    //打开文件
    FILE *fp;
    fp = fopen("./a.txt", "r");
    if (fp == NULL)
    {
        perror("fopen err");
        return -1;
    }
    printf("fopen success\n");
    //2读写操作
    // int ch = fgetc(fp);
    // printf("%c\n", ch);//h
    // fputc('a', fp);
    // ch = fgetc(fp);//l
    // printf("%c\n", ch);
    // fputc('b', fp);
    // ch = fgetc(fp);//0
    // printf("%c\n", ch);
    // ch = fgetc(fp);//
    // printf("%c\n", ch);
    // //检测读到文件末尾
    // if(feof(fp))
    //     printf("end...\n");
    // fputc('k', fp);
    // if (ferror(fp))
    //     printf("err\n");
    //终端
    int ch = fgetc(stdin);
    fputc(ch,stdout);
    //关闭文件
    fclose(fp);

    return 0;
}

feropen

FILE * freopen(const char *pathname,  const char *mode,  FILE* fp)
功能:将指定的文件流重定向到打开的文件中
参数:path:文件路径
mode:打开文件的方式(同fopen)
      fp:文件流指针
返回值:
    成功:返回文件流指针
    失败:NULL
#include 

int main(int argc, char const *argv[])
{
    printf("hello\n");
    FILE *fp;
    fp = freopen("a.txt", "w+", stdout);
    if(NULL==fp)
    {
        perror("freopen err");
        return -1;
    }
    printf("world\n");
    freopen("/dev/tty","r+",stdout);
    printf("nihao\n");
    return 0;
}

打印错误信息perror

void perror(const char *s);
	功能:根据errno值打印对应的错误信息
	参数:    s:提示语句
	返回值:空

关闭文件

close

int fclose(FILE* stream);
功能:关闭文件
参数:stream:文件流

读写操作

fgetc(读取单个字符)

格式:int  fgetc(FILE * stream)
功能:从文件中读取一个字符
参数:stream:文件流
返回值:
    成功:读到的字符
    失败或读到文件末尾:EOF(-1)
#include 

int main(int argc, char const *argv[])
{
    //终端
    // char buf[32];
    // fgets(buf, 5, stdin);
    // printf("buf:%s\n", buf);//hell
    //文件
    FILE *fp = fopen("./a.txt", "r+");
    if (fp == NULL)
    {
        perror("fopen err");
        return -1;
    }
    printf("fopen okk\n");
    char buf[32];
    fgets(buf, 32, fp);
    //printf("buf:%s\n",buf);
    //fputs(buf, stdout);
    fputs(buf, fp);
    
    return 0;
}

fputc(写入单个字符)

格式:int fputc(int c, FILE * stream)
功能:向文件中写入一个字符
参数:
    c:要写的字符
    stream:文件流
返回值:
    成功:写的字符的ASCII
    失败:EOF

fgets(读取一行)

格式:char * fgets(char *s,  int size,  FILE * stream);
功能:从文件中每次读取一行字符串
参数:
    s:存放字符串的地址
    size:一次读取的字符个数         
    stream:文件流
 返回值:
    成功:s的地址
    失败或读到文件末尾:NULL
特性:
    每次实际读取的字符个数为size-1个,会在末尾自动添加\0
    每次读一行,遇到\n后不再继续,读下一行

fputs(写入一行)

格式:int  fputs(const char *s,  FILE * stream);
功能:向文件中写字符串
参数:
    s:要写的内容
    stream:文件流
返回值:
    成功:非负整数
    失败:EOF

二进制读写

fread

格式:size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:从文件流读取多个元素
参数:
    ptr :用来存放读取元素
    size :元素大小  sizeof(数据类型)
    nmemb :读取元素的个数
    stream :要读取的文件
返回值:
    成功:读取的元素的个数;
    读到文件尾: 0
    失败: -1 
#include 

int main(int argc, char const *argv[])
{
    FILE *fp = fopen("./a.txt", "w+");
    if (NULL == fp)
    {
        perror("fopen err");
        return -1;
    }
    printf("fopen ok\n");
    //二进制读写
    float arr[3] = {1.23, 4.56, 7.89};
    //写arr到文件中
    fwrite(arr, sizeof(float), 3, fp);
    rewind(fp);//将文件指针定位到开始位置
    float new[3] = {0};
    //从文件中将数据读出来
    fread(new, sizeof(float), 3, fp);
    printf("%.2f %.2f %.2f\n",
           new[0], new[1], new[2]);

    fclose(fp);
    return 0;
}

fwrite

格式:size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:按对象写
参数:
    ptr :用来存放读取元素
    size :元素大小  sizeof(数据类型)
    nmemb :读取元素的个数
    stream :要读取的文件
返回值:
    成功:写的元素个数
    失败 :-1

判断是否到文件结尾

feof

格式:int  feof(FILE * stream);
功能:判断文件有没有到结尾
返回:到达文件末尾,返回非零值

判断文件是否出错

ferror

格式:int ferror(FILE * stream);
功能:检测文件有没有出错
返回:文件出错,返回非零值

练习1:

用fgets fputs实现cat功能

注意:cat是查看文件名

#include 

int main(int argc, char const *argv[])
{
    //cat 功能
    /*打开文件,循环读文件并输出到终端,
    当读到文件末尾EOF,feof结束循环 */
    if (argc != 2)
    {
        printf("please input %s ", argv[0]);
        return -1;
    }
    //1.打开文件
    FILE *fp = fopen(argv[1], "r");
    if (NULL == fp)
    {
        perror("fopen err");
        return -1;
    }
    printf("fopen success\n");
    //2.循环读文件
    int ch;
    while (1)
    {
        ch = fgetc(fp);
        // if (feof(fp))
        //     break;
        if (ch == EOF)
            break;
        fputc(ch, stdout);
    }
    //关闭文件
    fclose(fp);
    return 0;
}

练习2:

用fgets计算文件行数 (wc -l 文件名)

#include 
#include 
#include 
//打开文件,用循环按行读写,每读一行,num++,最后关闭文件;换行的标准是“\n”,判断“\n”的个数
int main(int argc, char const *argv[])
{
    if(argc!=2)
    {
        printf("please input filename\n");
        return -1;
    }
    FILE *fp=fopen(argv[1],"r");
    if(NULL == fp)
    {
        perror("fp error");
        return -1;
    }
    printf("fp success\n");
    char arr[32];
    int num=0;
    while(fgets(arr,32,fp) != NULL)//可以直接用数组的大小,遇到“\n”或数组读满,就进行下一次循环
    {
        if(arr[strlen(arr)-1]=='\n')//strlen不计算"\0"
            num++;
    }
    printf("%d %s\n",num,argv[1]);
    fclose(fp);
    return 0;
}

练习3:

用fread fwrite实现cp功能,复制一张图片

#include 
#include 
#include 

//实现cp功能,將一张图片复制到另一个文件里面,打开两个文件,读源文件写到目标文件中,关闭文件
int main(int argc, char const *argv[])
{
    if(argc!=3)//打开了三个文件
    {
        printf("please input filname\n");
        return -1;
    }
    FILE *f=fopen(argv[1],"r");
    FILE *fp=fopen(argv[2],"w+");
    if(NULL == f)
    {
        perror("f error\n");
        return -1;
    }
    if(NULL == fp)
    {
        perror("fp error\n");
        return -1;
    }
    printf("fp success\n");
    char arr[1024];
    int x;
    while (!feof(f))//用循环读图片,因为不知道图片的大小,为了防止图片没有复制成功
    {
        x=fread(arr,sizeof(char),1024,f);//fread的返回值是数组的长度,用x返回arr的最新长度,x为了防止图片复制的和原图片复制的不一样
        fwrite(arr,sizeof(char),x,fp);//读的时候只读数组的长度
    }
    
  
    return 0;
}

定位操作

rewind

void rewind(FILE *stream);
功能:将文件位置指针定位到起始位置
参数:stream:文件流

fseek

格式:int fseek(FILE *stream, long offset, int whence);
功能:文件的定位操作
参数:
    stream:文件流
    offset:偏移量:正数表示向后文件尾部偏移,负数表示向文件开头偏移
    whence:相对位置:
           SEEK_SET:相对于文件开头
           SEEK_CUR:相对于文件当前位置
           SEEK_END:相对于文件末尾
返回值:
    成功:0
    失败:-1   
注:当打开文件的方式为a或a+时,fseek不起作用
#include 

int main(int argc, char const *argv[])
{
    FILE *fp = fopen("./a.txt", "w+");
    if (fp == NULL)
    {
        perror("fopen err");
        return -1;
    }
    printf("fopen success\n");
    fputs("hello world\n", fp);
    printf("%ld\n",ftell(fp));//12
    //相对于结束位置向前偏移了3个字符,写了n
    fseek(fp, -3, SEEK_END);
    fputc('n', fp);
    printf("%ld\n",ftell(fp));//10
    //相对于开始位置向后偏移了2个字符,写了nihao
    fseek(fp, 2, SEEK_SET);
    fputs("nihao", fp);
    printf("%ld\n",ftell(fp));//7
    //相对于当前位置向前偏移了2个字符,读字符
    fseek(fp, -2, SEEK_CUR);
    printf("%c\n", fgetc(fp));
    printf("%ld\n",ftell(fp));//6

    fclose(fp);
    return 0;
}

ftell

格式:long ftell(FILE *stream);
功能:获取当前的文件位置
参数:要检测的文件流
返回值:成功:当前的文件位置,出错:-1

对比命令

diff

格式:diff 文件名1 文件名2

功能:ddiff是Linux命令,iff以逐行的方式,比较文本文件1和2的异同处。如果指定要比较目录,则diff会比较目录中相同文件名的文件,但不会比较其中子目录。

你可能感兴趣的:(IO进程,linux,运维,ubuntu,交互,笔记)