> 技术文档 > 华清远见25072班I/O学习day1

华清远见25072班I/O学习day1


重点内容:

IO基础:

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

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

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

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

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

        1、标准IO属于库函数,文件IO属于系统调用

        2、标准IO操作的是文件指针,文件IO操作的是文件描述符

        3、标准IO有缓冲器,文件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:

标准IO提供的内容:

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

        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会提供三种缓冲区:

                全缓存 行缓存 不缓存

FILE结构体:

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

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

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

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

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

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

打开文件函数:fopen

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

        功能:创建或打开一个名为pathname的文件,通过 mode 的方式进行,并返回一个用于操作文件的指针

        参数1:要被打开或者创建的文件名,如果文件存在,则会正常打开,如果文件不存在,根据打开方式而定

        参数2:文件打开方式的起始字母

                r:以只读的形式打开文件,如果文件不存在,直接报错,打开文件后光标在开头部分

                r+:以读写的形式打开文件,如果文件不存在,直接报错,打开文件后光标在开头部分

                w:以只写的形式打开文件,如果文件存在,则清空,如果文件不存在则创建,光标在文件开头部分

                w+:以读写的形式打开文件,如果文件存在,则清空,如果文件不存在则创建,光标在文件开头部分

                a:以追加(结尾写)的形式打开文件,如果文件不存在则创建文件,光标文件结尾部分                 a+:以追加读的形式打开文件, 如果文件不存在则创建文件,如果第一次操作是读数据,则光标在开头, 如果是写数据,则光标在结尾

                返回值:成功打开返回打开的文件指针,失败返回NULL并置位错误码

关闭文件函数:fclose

        int fclose(FILE *stream);

        功能:将给定的文件指针,与其操作的文件断开连接

        参数:已经打开的文件指针

        返回值:成功关闭返回0,失败返回-1并置位错误码

单字符数据读写操作(fgetc、fputc)

        int fputc(int c, FILE *stream);

        功能:将给定的字符c,从程序输出到stream指向的文件中

        参数1:要输出的字符

        参数2:目的文件的文件指针

        返回值:成功输出后,返回输出的那个字符对于的ascii值,失败返回-1(EOF)并置位错误码

        int fgetc(FILE *stream);

        功能:从stream指针指向的文件中读取当前的一个字符,以返回值的形式返回给程序

        参数:要操作的文件对应的文件指针

        返回值:打开的文件当前光标所在的那个字符,失败返回-1并置位错误码

格式化输入输出数据(fprintf、fscanf)

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

        功能:从stream指向的文件中,以format字符串格式读取下来数据,放到后面的地址列表中

        参数1:文件指针,可以是特殊文件指针stdin,也可以是普通文件指针

        参数2:格式化字符串,可以包含%d、%c、%s。。。

        参数3:可变参数

        返回值:成功返回读取数据的项数,失败返回-1并置位错误码

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

        功能:向stream指向的文件中写入一个格式串

        参数1:指定文件指针,可以是普通文件指针,也可以是特殊文件指针

        参数2:格式串,可以包含%d、%c、%s。。。

        参数3:可变参数

        返回值:成功返回输出的字符个数,失败返回-1并置位错误码


作业:

使用fgets、fputs完成两个文件的拷贝,要求文件名使用外部传承

将注册和登录代码自己完成一边

程序源码:

#include
#include
#include
//定义注册函数
int do_register()
{
    char register_username[20] = \"\";         //注册用户名
    char register_pwd[20] = \"\";            //注册密码
    printf(\"请输入注册账号:\");
    fgets(register_username, sizeof(register_username), stdin);   //从终端获取字符串
    register_username[strlen(register_username)-1] = 0;   //将\'\\n\'换成‘\\0’
    printf(\"请输入注册密码:\");
    fgets(register_pwd, sizeof(register_pwd), stdin);
    register_pwd[strlen(register_pwd)-1] = 0;
    //将上面的数据写入到文件中
    //以只写的形式打开文件
    FILE *fp = NULL;
    if((fp=fopen(\"./user.txt\", \"a\")) == NULL)
    {
        printf(\"文件打开失败\\n\");
        return -1;
    }
    //将账号和密码写入到文件中,以空格隔开   账号 密码\\n
    fprintf(fp, \"%s %s\\n\", register_username, register_pwd);
    fprintf(stdout, \"注册成功\\n\");
    //关闭文件
    fclose(fp);
    return 0;
}
//定义登录函数
int do_login()
{
    //定义相关变量
    char login_username[20] = \"\";
    char login_pwd[20] = \"\";
    printf(\"请输入登录账号:\");
    fgets(login_username, sizeof(login_username), stdin);   //从终端获取字符串
    login_username[strlen(login_username)-1] = 0;   //讲\'\\n\'换成‘\\0’
    printf(\"请输入登录密码:\");
    fgets(login_pwd, sizeof(login_pwd), stdin);
    login_pwd[strlen(login_pwd)-1] = 0;
    //从文件中读取内容进行比较
    char buf_username[20] = \"\";        //存放文件中的账号
    char buf_pwd[20] = \"\";             //存放文件中的密码
    //以只读的形式打开文件
    FILE *fp = NULL;
    if((fp = fopen(\"./user.txt\", \"r\")) == NULL)
    {
        printf(\"文件打开失败\\n\");
        return -1;
    }
    while(1)
    {
        int res = fscanf(fp, \"%s %s\", buf_username, buf_pwd);
        if(res == EOF)
        {
            printf(\"登录失败\\n\");
            return -1;
        }
        //判断是否与登录账号和密码匹配
        if(strcmp(login_username,buf_username)==0 && strcmp(login_pwd,buf_pwd)==0)
        {
            printf(\"登录成功\\n\");
            break;
        }
    }
    //关闭文件
    fclose(fp);
    return 0;
}
/************************主程序************************/
int main(int argc, const char *argv[])
{
    //先做一个菜单
    int menu = -1;
    while(1)
    {
        printf(\"\\t\\t===========1、注册=========\\n\");
        printf(\"\\t\\t===========2、登录=========\\n\");
        printf(\"\\t\\t===========0、退出=========\\n\");
        printf(\"请输入功能:\");
        scanf(\"%d\", &menu);
        getchar();                    //吸收scanf留下的回车
        //多分支选择
        switch(menu)
        {
        case 1:
            {
                do_register();         //执行注册操作
            }
            break;
        case 2:
            {
                int r = do_login();           //执行登录操作
                //如果r==0表示成功,继续做其他任务
                //如果r!=0表示登录失败,继续登录
            }
            break;
        case 0: exit(0);
        default:printf(\"您输入的功能有误,请重新输入\\n\");
        }
    }
    return 0;
}
 

思维导图:

牛客网刷题: