IO(一)——IO基础及标准IO

一、IO基础

1、文件的概念:

1、文件:一组相关数据的有序集合
2、文件名:这个数据集合的名称

2、linux支持的文件类型

常规文件:-

ASCII码文件

二进制的文件

目录:d

字符设备:c

块设备:b

有名管道:p

套接口:s

符号链接:l
可记做:lsp-bcd

3、系统调用

1、用户空间进程访问内核的接口

2、把用户从底层的硬件编程中解放出来

3、极大的提高了系统的安全性

4、使用户程序具有可移植性

5、操作系统的一部分

4、库函数

1、库函数为了实现某个功能而封装起来的API集合

2、提供统一的编程接口,更加便于应用程序的移植

3、是语言或者应用程序的一部分

二、标准IO

1、文件指针

FILE指针:每个被使用的文件都在内存中开辟一个区域,用来存放文件的有关信息,这些信息是保存在一个结构体类型的变量中,该结构体类型是由系统定义的,取名为FILE。

标准I/O库的所有操作都是围绕流(stream)来进行的,在标准I/O中,流用FILE *来描述。

标准I/O库是由Dennis Ritchie在1975年左右编写的


2、流(stream)

定义:所有的I/O操作仅是简单的从程序移进或者移出,这种字节流,就称为流。

分类:文本流/二进制流。

1.文本流
定义:在流中处理的数据是以字符出现。在文本流中,’\n’被转换成回车符CR和换行符LF的ASCII码0DH和0AH。而当输出时,0DH和0AH被转换成’\n’

数字2001在文本流中的表示方法为  ‘2’  ‘0’  ‘0’  ‘1’
ASCII:    50  48  48  49

2.字节流
定义:流中处理的是二进制序列。若流中有字符,则用一个字节的二进制ASCII码表示;若是数字,则用对应的二进制数表示。对’\n’不进行变换

数字2001在二进制流中的表示方法为 00000111  11010001。

每个进程默认打开三个流:

  1. stdin:标准输入
  2. stdout:标准输出
  3. stderr:标准错误

3、缓存分类

1.全缓存:
刷新(fflush):标准I/O的写操作。

当填满I/O缓存,或者满足一定的条件后,就会执行刷新操作。
2.行缓存
当输入输出过程中遇到换行符('\n')时,进行I/O操作

当流遇到一个终端时,为典型的行缓存
3.不缓存
准I/O库不对字符进行缓冲,例如stderr。

很多的人机交互界面要求不可全缓存。

标准出错决不会是全缓存的。

4、文件操作

流程:打开文件 --> 操作文件 --> 关闭文件。

打开文件:fopen /关闭文件:fclose
函数原型:
FILE *fopen (const char *path, const char *mode);
返回值:成功打开文件的流指针,失败NULL
const char *path:要打开的文件
const char *mode:打开的方式

mode的选项:

r或rb :打开只读文件,该文件必须存在。

r+或r+b :打开可读写的文件,该文件必须存在。

w或wb :打开只写文件,若文件存在则文件长度清为0,即会擦些文件以前内容。若文件不存在则建立该文件。

w+或w+b或wb+ :打开可读写文件,若文件存在则文件长度清为零,即会擦除文件以前内容。若文件不存在则建立该文件。

a或ab :以追加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。

a+或a+b或ab+ :以追加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,从头读取,但是写入的数据会被加到文件尾后,即文件原先的内容会被保留。

关闭文件:fclose

关闭文件函数原型
int fclose(FILE *stream);
FILE *stream:要关闭的文件流指针

fopen/fclose示例

#include <stdio.h>

int main(int argc, char *argv[])
{ 
    FILE * fp= fopen("1.txt","r");  // 打开1.txt文件 
    if( NULL == fp )  // 如果打开文件失败,则输出错误原因
    {
        perror("fopen ");
        return -1;
    }
    fclose(fp); // 关闭文件
    return 0;
} 

操作文件:fread/fwrite
读文件函数原型:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
返回值:成功>0表示实际读取字节数,==0表示读到文件末尾 失败 -1出错 
void *ptr:存储读取内容的缓存首地址
size_t size:每次读取的字节数
size_t nmemb:读取多少次
FILE *stream:读取的目标流

fread示例

#include <stdio.h>
#include <string.h>
#define N 64
int main(int argc, char *argv[])
{ 
    //判断命令行参数个数
    if( 2 > argc )
    {
        printf("argv:%s<filename>\n",argv[0]);
        return -1;
    }

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

    //定义缓冲区
    char a[N] = {0};

   while(1)
    {
        int ret = fread(a,1,1,fp); //将打开文件的内容写入缓冲区中

        if( 0 == ret ) // ret为fread返回值,为0则到达文件末尾,结束循环
        {
            break;
        }
        printf("%s",a);
       memset(a,0,N);
        }
    
    //关闭文件
    fclose(fp);
    return 0;
} 

写文件函数原型:
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
返回值:实际写入字节数,失败-1
const void *ptr:要写入的数据所在缓存首地址
size_t size:每次写入字节数
size_t nmemb:写入多少次
FILE *stream:写入的文件流指针

fwrite示例

#include <stdio.h>
#include <string.h>
#define N 64
int main(int argc, char *argv[])
{ 
    //判断命令行参数个数
    if( 2 > argc )
    {
        printf("argv:%s<filename>\n",argv[0]);
        return -1;
    }

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

    //定义缓冲区
    char a[N] ;

    
    while(1)
    {

        fgets(a,N-1,stdin); // 从终端获取输入到缓冲区
        if( 0 == strcasecmp(a,"quit\n"))
        {
            break;
        }
        fwrite(a,strlen(a),1,fp); // 将缓冲区内容写到打开的文件中
    }
    
    //关闭文件
    fclose(fp);
    return 0;
} 

fputs和fgets

fgets函数用于从文本文件中读取一行字符串,并将其存储到指定的字符串变量中。它的原型如下:
char *fgets(char *str, int n, FILE *stream);
其中,str是指向字符数组的指针,用于存储读取到的字符串;n是最多要读取的字符数,包括最后
的'\0';stream是要读取的文件指针。如果读取成功,函数返回指向存储的字符串的指针,否则返回
NULL。

fputs示例用法:

#include <stdio.h>

int main() {
    FILE *file = fopen("file.txt", "r"); //打开文件
    if (file) //如果文件存在
    {
        char str[100];
        while (fgets(str, sizeof(str), file) != NULL)  //文件输入到缓冲区且不为空
        {
            printf("%s", str);
    	}
        fclose(file); //关闭文件
    }
    return 0;
}

fputs函数用于将字符串写入文本文件。它的原型如下:
int fputs(const char *str, FILE *stream);
其中,str是要写入的字符串;stream是要写入的文件指针。如果写入成功,返回非负数,否则返回
EOF。

fputs示例用法:

#include <stdio.h>

int main() {
    FILE *file = fopen("file.txt", "w"); // 打开文件
    if (file) {
        fputs("Hello, World!", file);//将"Hello, World!"写到文件中
        fclose(file);//关闭文件
    }
    return 0;
}

fprintf/fscanf
fprintf原型如下:
int fprintf(FILE *stream, const char *format, ...);
其中,stream是一个指向要写入数据的文件指针,format是一个字符串,包含要打印的文本和格式控制符,...表示可变数量的参数,用于填充格式控制符中的占位符。


fprintf函数的用法与printf函数类似,只是需要指定输出到哪个文件中。stream可以是标准输出流(stdout)或标准错误流(stderr),也可以是通过fopen函数打开的文件指针。

fprintf示例用法:

#include <stdio.h>

int main() {
    FILE *file = fopen("output.txt", "w");

    if (file != NULL) {
        int age = 20;
        float height = 1.75;
        char name[] = "John";

        fprintf(file, "My name is %s.\n", name);
        fprintf(file, "I am %d years old.\n", age);
        fprintf(file, "I am %.2f meters tall.\n", height);

        fclose(file);
    }

    return 0;
}

以上代码将输出打印到名为"output.txt"的文件中。


fscanf其原型如下:
int fscanf(FILE *stream, const char *format, ...);
其中,stream是一个指向要读取数据的文件指针,format是一个字符串,包含了要读取的数据类型和格
式控制符,...表示可变数量的指针参数,用于读取不同类型的数据并将其存储到相应的变量中。


fscanf函数的用法与scanf函数类似,只是需要指定从哪个文件中读取数据。stream可以是标准输入流
(stdin),也可以是通过fopen函数打开的文件指针。

fscanf示例用法:

#include <stdio.h>

int main() {
    FILE *file = fopen("input.txt", "r");

    if (file != NULL) {
        int age;
        float height;
        char name[50];

        fscanf(file, "%s", name);
        fscanf(file, "%d", &age);
        fscanf(file, "%f", &height);

        printf("My name is %s.\n", name);
        printf("I am %d years old.\n", age);
        printf("I am %.2f meters tall.\n", height);

        fclose(file);
    }

    return 0;
}

以上代码从名为"input.txt"的文件中读取数据,并通过printf函数将其打印到屏幕上。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值