【IO 进程】《标准IO》(一)

IO是什么?
IO是输入input输出output的首字母缩写形式,直观意思是计算机输入输出,它描述的是计算机的数据流动的过程,因此IO第一大特征是有数据的流动;指的是计算机系统与外部设备之间进行数据交换的过程。输入是指将外部数据传输到计算机系统中,输出是指将计算机系统中的数据传输到外部设备中。另外,对于一次IO,它究竟是输入还是输出,是针对不同的主体而言的,不同的主体有不同的描述。学习的目的就是为了将数据存储以及对于文件的操作。IO操作是计算机系统中的重要组成部分,它使计算机能够与用户交互,接收用户的输入,并将计算结果输出给用户。通过IO操作,计算机可以读取外部数据、存储数据、显示信息、传输数据等。
IO的分类
标准IO(高级磁盘IO)

标准C库提供的,可以跑在各个系统上

文件IO(低级磁盘IO)
标准IO和文件IO的区别
标准IO:通用的

访问效率高

文件建立了缓存

断电容易丢失数据只能访问普通文件
文件IO:linux专用访问效率低不容易丢失数据针对linux下的所有文件

共同点:

  1. 输入输出:标准IO和文件IO都是用于处理输入和输出的操作,都提供了输入数据和写入输出数据的功能。
  2. 函数库:标准IO和文件IO都是由编程语言提供的函数库来支持。它们提供了一组函数和方法,用于处理输入输出操作。
  3. 数据传输:无论是标准IO还是文件IO,都涉及数据在不同设备或存储介质之间的传输。标准IO通过终端设备玉用户进行交互,文件IO通过文件进行数据的读写操作。                             
标准IO 

概念:

标准IO:是在c库中定义的一组专门用于输入输出的函数

特点
  • 通过缓冲机制减少系统调用,提高效率。
  • 围绕 进行操作,流用 FILE* 来描述。

缓存区

标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头文件中的定义,具有一定的可移植性。标准I/O库处理很多细节。例如缓存分配,以优化长度执行I/O等。标准的I/O提供了三种类型的缓存。

(1)全缓存:当填满标准I/O缓存后才进行实际的I/O操作。 
(2)行缓存:当输入或输出中遇到新行符时,标准I/O库执行I/O操作。 
(3)不缓存:stderr就是了。

  1. 全缓存:和文件相关(所以不需要\n)

刷新全缓存:

  • 程序正常退出
  • 强制刷新:fflush(NULL);
  • 缓存区满

2.行缓存:和终端相关

 刷新标准输出 缓存的条件:

  • \n
  • 程序正常退出
  • 强制刷新:fflush(NULL);
  • 缓存区满
3.不缓存:也就是没有缓存区,标准错误。

当我们每次要在终端打印数据时,并不是将数据直接发送给标准输出设备,也就是并直接发送给显示器,而是将要打印的数据先存放到缓存区,当缓冲存数据满时,或者遇到\n,或者程序结束时,或者手动刷新缓存区时,缓冲区才会把数据传输到标准输出设备中,也就是显示器中进行输出。但是全缓存不能用\n刷新缓存

函数接口

1.打开文件fopen

man 3 fopen
FILE *fopen(const char *path, const char *mode);
功能:打开文件
参数:
    path:打开的文件路径
    mode:打开的方式
        r:只读,当文件不存在时报错,文件流定位到文件开头
        r+:可读可写,当文件不存在时报错,文件流定位到文件开头
        w:只写,文件不存在创建,存在则清空
        w+:可读可写,文件不存在创建,存在则清空
        a:追加(在末尾写),文件不存在创建,存在追加,文件流定位到文件末尾
        a+:读和追加,文件不存在创建,存在追加,读文件流定位到文件开头,写文件流定位到文件末尾
注:当a+的方式打开文件时,写只能在末尾进行追加,定位操作是无法改变写的位置,但是可以改变读的位置

返回值:
成功:文件流
失败:NULL,并且会设置错误码

2.关闭文件 fclose

int fclose(FILE*stream)
功能:关闭文件
参数:stream:文件流
#include <stdio.h>

int main(int argc, char const *argv[])
{
    FILE *fp;
    //1.打开文件
    //fp = fopen("test.txt", "r"); //如果不存在会错误,因为只读r模式
    fp = fopen("test.txt", "w");
    if (NULL == fp)
    {
        perror("fopen err");
        // while(1);  //标准错误不缓存,错误信息会打印
        return -1;
    }
    printf("fopen success\n");

    //2.关闭文件
    fclose(fp);
    return 0;
}

文件读写操作

每次读写一个字符:fgetc()、fputc()

每次读一个字符fgetc()
int fgetc(FILE *stream);
功能:从文件中读取一个字符,并将当前文件指针位置往后移动一个字符。
参数:stream :文件流
返回值:成功:读到的字符
         失败或读到文件末尾:EOF(-1)

每次写一个字符fputc()
int fputc(int c,FILE*stream);
功能:向文件中写入一个字符,成功写入文件指针会自动向后移动一个字节位置。
参数:c:要写的字符
    stream:文件流
返回值:成功:写的字符的ASCII
        失败:EOF(-1);
对文件的读写
#include <stdio.h>

int main(int argc, char const *argv[])
{
    FILE *fp;
    //1.打开文件
    fp = fopen("test.txt", "r+");
    if (NULL == fp)
    {
        perror("fopen err");
        return -1;
    }
    printf("fopen success\n");

    char ch = fgetc(fp);
    printf("%d %c\n", ch, ch); //104 h

    ch = fgetc(fp);
    printf("%d %c\n", ch, ch); //101 e

    fputc('a', fp); //向文件中写个a
    fputc('b', fp); //向文件中写个b

    ch = fgetc(fp);
    printf("%d %c\n", ch, ch); //-1 EOF 因为以及到末尾了

    //2.关闭文件
    fclose(fp);
    return 0;
}
对终端的读写
#include <stdio.h>

int main(int argc, char const *argv[])
{
    char ch;
    ch = fgetc(stdin); //相当于getchar()
    printf("%d %c\n", ch, ch);

    fputc(ch, stdout); //相当于putchar()
    fputc(10, stdout);
    fputc('b', stdout);
    return 0;
}

补充:feof和ferror

feof
int feof(FILE*stream);
功能:判断文件有没有到结尾,也就是当前位置后面还有没有字符
返回:如果到达文件末尾,返回非零值。如果后面还有字符返回0;

text.txt

           

第一次fgetc()的是a,此时,指针知道a后面,后面还有一个EOF,所以要fgetc()两次,里面才空,所以输出aaa

ferror
int ferroe(FILE* stream)
功能:检测文件有没有出错
返回:文件出错,返回非零值,如果没有出错,返回0.

练习:cat文件名

/* cat 文件名:查看文件内容,显示到终端。

步骤:

1.打开文件 fopen

2.循环用fgetc获取文件内容

3.当读到文件末尾标志EOF时结束

4.将读取文件内容用fputc打印到终端

5.关闭文件

*/

int main(int argc, char const *argv[])
{
    if (argc != 2)
    {
        printf("err: %s <filename>\n", argv[0]); //提示一下正确的格式
        return -1;
    }

    //1.打开文件
    FILE *fp = fopen(argv[1], "r");
    if (NULL == fp)
    {
        perror("fopen err");
        return -1;
    }

    //2.循环用fgetc读文件,只要读到就fputc打印到终端
    char ch;
    while ((ch = fgetc(fp)) != EOF)
        fputc(ch, stdout);   //将读到字符打印到终端
  
    //3. 关闭文件
    fclose(fp);

    return 0;
}

每次一个字符串的读写fgets()和fputs()

fgets() 

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

fputs()

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值