学习有感:简述标准IO

        在了解标准IO之前,我们要先了解一些关键的概念。

此处的IO表示输入与输出;

目录

分类

基本分类

linux系统文件分类

标准IO缓存分类

 

标准IO:是由ANSI C标准提供的C语言标准函数库

man 手册使用简介

文件基本操作:

1.打开---------fopen()

2.读取----------fread()等等.....

3.写入 fwrite()等等

4.关闭 fclose()

其他标准IO介绍

fseek()

ftell()

rewind()

fprintf()

sprintf()格式化字符串函数


分类

基本分类

                1. 文本文件(ascii文件):文件中的内容使用ascii码或者字符来表示,例如日常的txt文件

                2.二进制文件:文件中存放二进制数据,例如我们经常打开的系统文件中有一些是看不懂的“乱码”。这些文件的内容是用二进制来记录的。

                两个文件类型对于计算机来说在物理存储上没有区别(最终都会以二进制的形式处理),在逻辑上有所差别(文件的编码方式不同)

linux系统文件分类

-普通文件                 -

-管道文件                p

-字符设备文件        c

-连接文件                l

-套接字文件            s

-块设备文件             b

-目录文件                d

可在linux终端上通过命令ls -l 查看当前目录下的各种文件类型和详细信息

ls -l

每一段的首字符就是该文件的类型表示。 

lrwxrwxrwx   1 root root         7 8月   4  2021 bin -> usr/bin
drwxr-xr-x   4 root root      4096 6月  23 09:10 boot
drwxrwxr-x   2 root root      4096 8月   4  2021 cdrom
drwxr-xr-x  20 root root      4240 6月  17 09:05 dev
drwxr-xr-x 132 root root     12288 6月  22 13:48 etc
drwxr-xr-x   4 root root      4096 4月  29 14:15 home
lrwxrwxrwx   1 root root         7 8月   4  2021 lib -> usr/lib
lrwxrwxrwx   1 root root         9 8月   4  2021 lib32 -> usr/lib32
lrwxrwxrwx   1 root root         9 8月   4  2021 lib64 -> usr/lib64
lrwxrwxrwx   1 root root        10 8月   4  2021 libx32 -> usr/libx32

标准IO缓存分类

  • 全缓存:文件的读写
    • 刷新条件
      • ffulsh刷新
      • 程序结束
      • 缓存区满
  • 行缓存:标准输入与输出的缓存方式
    • 刷新条件
      • ffulsh刷新
      • 程序结束
      • 缓存区满
      • 遇到'\n'
  • 无缓存:直接输出(stderr)

标准IO:是由ANSI C标准提供的C语言标准函数库

什么是ANSI c标准

        文件流:表示数据像水流一样,不间断地进行传输,所有的I/O操作仅是简单的从程序移进或者移出,这种字节流,就称为流。

        FILE *是文件指针类型,该类型是一个结构体,该结构体描述了文件相关的信息,每一个应用程序会默认定义三个文件流指针:stdin,stdout,stderr

  1. stdin        标准输入 在函数中使用可以从键盘接收输入的字符串
  2. stdout      标准输出
  3. stderr       标准错误

stdout与stderr都是将数据输出到终端上,不过stdout是行缓存,需要遇到换行时才进行输出。而stderr无缓存,会直接输出。例子如下,输出结果为“World !Hello”,各位不妨试试在“Hello”处加上一个“\n”或者在两个fprintf中间加上“fflush(stdout);”看看结果有什么不同

#include <stdio.h>

int main(int argc, char *argv[])
{ 
    fprintf(stdout,"Hello ");

    fprintf(stderr,"World!");
            
    return 0;
} 

man 手册使用简介

在IO阶段的学习中有大量的新函数需要学习,要时刻记住“有困难,找男人(man)”,man手册有三种打开方法

man 1  查看shell命令              

man 2  查看系统调用

man 3 查看c标准库

文件基本操作:

在有了一些基本了解之后就来到了基本操作函数学习。

1.打开---------fopen()

FILE * fopen(const char * path,const char * mode);

参数path字符串包含欲打开的文件路径及文件名
参数mode字符串则代表着流形态
mode有下列几种形态字符串:
r 只读,不会创建新文件,默认从开头进行读取

r+ 读写,不会创建新文件,默认从开头进行读取

w 只写,会创建新文件,默认从头写入,清空原文内容

w+ 读写,会创建新文件,有则清空原文件内容再开始写入。

a 只写,会创建新文件、文件不会清空、会以追加的方式写入内容

a+ 读写,会创建新文件、文件不会清空、会以追加的方式写入内容

b    以二进制流方式,需要与前面相组合使用    "rb"此处的组合不必在意先后顺序,怎么好看怎么来

返回值:NULL:表示错误返回

     正确返回文件流指针:该指针指向一个文件,后续可以直接使用该指针进行间接文件操作

使用fopen一定要进行错误判断,以防出现问题,例子如下:

假设当前目录下没有“1.txt”文件,此时有以下程序

int main()
{
		FILE *fp=fopen("1.txt","r");
		
		printf("end of file\n");
		return 0;
}
	此时终端正常返回end of file,但是程序已经出现错误。
因为当前目录下不存在1.txt文件,而“r”权限不会创建新文件,所以此处必定有错误

重新添加错误判断以后

int main()
{
		FILE *fp=fopen("1.txt","r");
		if(NULL == fp)
        {
			printf("fopen failed\n");
 
            return -1;
        }
		printf("end of file\n");
		return 0;
}

此时返回fopen failed,因为此时路径中根本没有1.txt

2.读取----------fread()等等.....

  1. int fgetc(FIEL*stream) :从指定的文件中读取一个字符,并且将字符返回

    {

            stream:文件流指针,上文fopen中创建的fp;

            返回值:成功fgetc会返回读取到的无符号字符;

                            失败或者到达文件末尾返回“EOF”

    }

            此处有一个问题:为什么返回的是字符返回值却使用int类型呢?因为在使用char类型时fgetc读取数据的时候可能会遇到二进制换算值为255的符号,例如一张图片中,代表像素颜色深浅的数据有0到255的范围,255在char类型中可能会被认为是-1,而返回值为-1可能会导致某些程序中止。所以选用int类型,int类型的-1为0xfffffffff相对于char类型的0xff来说数据范围增大很多,几乎不可能遇见这个大小的符号。(此处可能有些表述不清晰,望见谅)

  2. char *fgets(char *s,int size,FILE *stream);从指定的文件中读取一行的数据遇到'\n'结束

          size:想要读取一行文件内容的字节数       

           1. 当size的值小于等于文件中的一行数据大小时,显示读取size-1个数据,最后会默认添加一个'\0'
            2. 当size-1的值大于文件中的一行数据大小时,遇到'\n'正常结束
            3.两种情况都必须以'\0'为结束标志
            s:数据首地址
          **'\n'的ascii码为10,当fgets遇到10的字符时就会自动停止读取,在添加一个'\0'之后退出。此操作可能会导致文件内容出现丢失,所以不能将fgets用在文本文件(.txt)之外的文件读取。

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

               支持任意类型的以及任意数量的数据读取

            ptr:数据首地址
            size:每一个数据的字节大小    eg:读取整数数据 size = sizeof(int)
            nmemb:想要读取的数据个数
            stream:文件流指针

        返回值:错误或者到达文件末尾:返回0或者比nmemb小的整数

                        正确:返回读取数据的个数

         判断错误或者文件末尾情况有两个函数

feof():判断是否达到文件末尾
        用法:if(foef(fp) != 0)
    ferror():判断文件操作是否出错
        用法:if(ferror(fp) != 0)

3.写入 fwrite()等等

  1.        int fputc(int ch,FILE*stream) 一次写入一个字符

     返回值:错误返回EOF

                    正确返回写入的字符

  2.  int fputs(const char *s,FILE *stream)

         向文件写入一串数据,s表示数据的首地址
        错误返回EOP   正确返回非负数

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

返回值 :错误 :0或者小于nmemb的数

                正确:返回成功写入的数据个数

4.关闭 fclose()

        int fclose(FILE *stream)

        正常关闭返回0;否则返回EOF

fclose作用

        一.清空相关的缓冲区

        二.释放内存

其他标准IO介绍

fseek()

可以修改文件读写定位指针指向的位置

 int fseek(FILE *stream, long offset, int whence);

offset:偏移量,可以为负数;

whence:

        SEEK_SET:回到文件开头位置;

        SEEK_CUR:在当前位置;

        SEEK_END:转移至文件末尾;

返回值:成功0;失败-1.

ftell()

返回当前文件流指针的位置,通常与fseek(先移动到文件尾)一起使用来计算文件的大小

 long ftell(FILE *stream);

rewind()

将文件流指针返回文件的开头,效果等同于,fseek(stream,0,SEEK_SET);

void rewind(FILE *stream);

fprintf()

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

将格式化的字符串写入到指定的文件当中

stream文件流指针;

format:格式控制字符串

....可变参数

sprintf()格式化字符串函数

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

将最多大小的字节(包括终止的空字节('\0'))写入str。

例子:

//每次调用都往文件里面存一组数据
int main(int argc, char *argv[])
{ 
    int tmp = 35;
    int hum = 56;
    int light = 1026;
    char buf[1024] = {0};
    sprintf(buf,"tmp:%d,hum:%d light:%d\n",tmp,hum,light);
//将数据存到buf中
    FILE *fp1 = fopen("1.txt","a");
    if(NULL == fp1)
    {
        perror("fopen fp1");
        return -1;
    }
   if(EOF== fputs(buf,fp1));
   return -1;
    fclose(fp1);
    return 0;
} 

希望这些对你有所帮助,如文章有错误之处,欢迎斧正.

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值