zoukankan      html  css  js  c++  java
  • c提高第六次课 文件读取

    一、基本概念
    1、文件分类
    普通文件:存放在硬盘中的文件
    设备文件:屏幕、键盘等特殊文件

    文本文件:ASCII文件,每个字节存放一个字符的ASCII码,打开文件看到的是文本信息
    二进制文件:数据按其在内存中的存储形式原样存放,打开文件看到的是乱码

    2、文件缓冲区(了解)
    ANSI C(标准C语言库函数)标准采用“缓冲文件系统”处理数据文件。

    写文件(设备文件除外),并不会直接写到文件中,会先放在缓冲区,默认情况下,关闭文件或缓冲区满了才写到文件。
    如果没有关闭文件,缓冲区也没有满,可以通过程序正常结束,或者人为刷新缓冲区fflush(fd)来把缓冲区的内容写到文件中。

    缓冲区了解一下即可,增加缓冲区只是为了提高效率,减少频繁交互的次数,我们写程序基本上不用关心。

    二、读写文件步骤
    1、打开文件
    //定义文件指针
    FILE *fp = NULL;
    fopen("c:\demo.txt", "w+"); //"c:\demo.txt" windows有效
    //"c:/demo.txt": 文件路径,可以是绝对路径和相对路径
    //"w+": 打开权限,读写方式打开,文件不存在则创建,写内容时,会清空原来内容再写
    //"r+":读写方式打开,文件不存在则报错
    fp = fopen("./demo.txt", "w+"); // 45度 "c:/demo.txt" linux windows都可用
    if (fp == NULL)
    {
    perror("fopen"); //打印错误信息
    return;
    }

    默认情况下,VS, Qt相对路径说明:
    1)编译代码时,相对路径相对于工程目录
    2)直接点击可执行程序,相对路径相对于可执行程序

    c语言中有三个特殊的文件指针无需定义、打开可直接使用:
    stdin: 标准输入 默认为当前终端(键盘)
    我们使用的scanf、getchar函数默认从此终端获得数据

    stdout:标准输出 默认为当前终端(屏幕)
    我们使用的printf、puts函数默认输出信息到此终端

    stderr:标准出错 默认为当前终端(屏幕)
    当我们程序出错或者使用: perror函数时信息打印在此终端

    fputc('a', stdout); //stdout -> 屏幕, 打印普通信息

    char ch;
    ch = fgetc(stdin); //std -> 键盘
    printf("ch = %c ", ch);

    //fprintf(stderr, "%c", ch ); //stderr -> 屏幕, 错误信息
    fputc(ch, stderr);


    2、读写文件
    1、输出,即为写,把buf中的内容写到指定的文件中
    2、输入,即为读,把文件中的内容取出放在指定的buf

    3、关闭文件
    fclose(fp);

    二、读写文件
    1、库函数的学习
    1)包含所需头文件
    2)函数名字
    3)功能
    4)参数
    5)返回值

    2、按照字符读写文件:fgetc()、fputc()
    1)写文件
    char *str = "111abcdefg12345678";
    int i = 0;
    for (i = 0; i < (int)strlen(str); i++)
    {
    //功能:往文件fp中写str[i],一个字符一个字符写
    //参数:str[i]:写入文件的字符,fp:文件指针
    //返回值:成功写入文件的字符,失败:-1
    fputc(str[i], fp);
    }

    2)读文件
    char ch;
    //feof(fp)判断文件是否到结尾,已经到结尾返回值为非0,没有到结尾返回值为0
    while ( !feof(fp) ) //如果文件没有结尾
    {
    //返回值:成功读取的字符
    ch = fgetc(fp);
    printf("%c", ch);
    }

    3、按照行读写文件:fputs()、fgets()
    1)写文件

    char *buf[] = { "11111111
    ", "aaaaaaaaaaaa
    ", "bbbbbbbbbbbb
    " }; //指针数组
    int i = 0;
    for (i = 0; i < 3; i++)
    {
    //功能:往文件fp写入一行内容buf[i]
    //参数:buf[i]:字符串首地址,fp:文件指针
    //返回值:成功:0,失败:非0
    fputs(buf[i], fp); 
    }

    2)读文件

    char buf[512] = {0};
    //从文件中读取一行内容(以"
    "作为标志),放在buf中
    //一次最大只能读sizeof(buf)-1,如果小于sizeof(buf)-1,则按实际大小读取
    //然后在字符串结尾自动加上字符‘’(转换为C风格字符串)
    //返回值:成功:读出的字符串,失败:NULL
    if (fgets(buf, sizeof(buf), fp) != NULL) 
    {
    printf("buf = %s", buf);
    }

    4、按照块读写文件:fread()、fwirte()
    typedef struct Stu
    {
    char name[50];
    int id;
    }Stu;
    Stu s[3];

    1)写文件
    //写文件,按块的方式写
    //s:写入文件内容的内存首地址
    //sizeof(Stu):块数据的大小
    //3:块数, 写文件数据的大小 sizeof(Stu) *3
    //fp:文件指针
    //返回值,成功写入文件的块数目,不是数据总长度
    int ret = fwrite(s, sizeof(Stu), 3, fp);
    printf("ret = %d ", ret);


    2)读文件
    //读文件,按块的方式读
    //s:放文件内容的首地址
    //sizeof(Stu):块数据的大小
    //3:块数, 读文件数据的大小 sizeof(Stu) *3
    //fp:文件指针
    //返回值,成功读取文件内容的块数目,不是数据总长度
    int ret = fread(s, sizeof(Stu), 3, fp);
    printf("ret = %d ", ret);

    5、按照格式化进行读写文件:fprintf()、fscanf()
    1)写文件
    //格式化写文件
    int a = 250;
    int b = 10;
    int c = 20;
    //和printf()用法一样,只是printf是往屏幕(标准输出)写内容
    //fprintf往指定的文件指针写内容
    //返回值:成功:写入文件内容的长度,失败:负数
    fprintf(fp, "Tom = %d, just like %d, it is %d", a, b, c);

    2)读文件

    int a, b, c;
    fscanf(fp, "Tom = %d, just like %d, it is %d", &a, &b, &c);
    printf("a = %d, b = %d, c = %d
    ", a, b, c);

    6、随机读写
    //文件光标移动到文件结尾
    //SEEK_SET:文件开头
    //SEEK_CUR:文件当前位置
    //SEEK_END:文件结尾
    fseek(fp, 0, SEEK_END);


    //获取光标到文件开头文件的大小ftell
    long size = ftell(fp);

    //文件光标恢复到开始位置
    rewind(fp);

    typedef struct Stu
    {
    char name[50];
    int id;
    }Stu;
    Stu tmp; //读第3个结构体

    //假如文件中写了三个结构体
    //从起点位置开始,往后跳转2个结构体的位置
    fseek(fp, 2*sizeof(Stu), SEEK_SET);
    //从结尾位置开始,往前跳转一个结构体的位置
    //fseek(fp, -1 * (int)sizeof(Stu), SEEK_END);
    int ret = 0;
    ret = fread(&tmp,sizeof(Stu), 1, fp);
    if(ret == 1)
    {
    printf("[tmp]%s, %d ", tmp.name, tmp.id);
    }

    //把文件光标移动到文件开头
    //fseek(fp, 0, SEEK_SET);
    rewind(fp);


    三、综合案例
    1、加密文件读写(使用别人写好的接口)
    2、配置文件读写(自定义接口)

     

  • 相关阅读:
    胜利大逃亡
    求最小环
    Prime算法
    网站根目录下没有正确的DNT.config文件 (不同类型错误更新中)
    Day4_代码重用与函数
    Day1_算法分析方法
    Day3_字符串操作与正则表达式
    错误解决一_call time passbyreference removed
    Day1_PHP快速入门
    silverlight 动态加载树形菜单[带图标],方法一
  • 原文地址:https://www.cnblogs.com/zyqy/p/9462102.html
Copyright © 2011-2022 走看看