7.2 文件

1.用 < 和 > 做重定向

file.c

#include<stdio.h>

int main(int argc, const char *argv)
{
    int num;
    int i1 = scanf("%i", &num);
    int i2 = printf("%d\n", num);
    printf("%d:%d\n", i1, i2);
    return 0;
}

这里写图片描述

2. API

  • FILE* fopen(const char* restrict path, const char* restrict mode);
    • mode:
      • r:打开只读
      • r+:打开读写,从文件头开始
      • w:打开只写。如果不存在则新建,如果存在则清空
      • w+:打开读写。如果不存在则新建,如果存在则清空
      • a:打开追加。如果不存在则新建,如果存在则从文件尾开始
      • ..x:只新建,如果文件已存在则不能打开
  • int fclose(FILE *stream);
  • fscanf(FILE*, …);
  • fprintf(FILE*, …);
#include<stdio.h>

int main(int argc, const char *argv)
{
    FILE *fp = fopen("text.txt", "r");// text.txt的内容是:12345 
    if(fp)
    {
        int num;
        fscanf(fp, "%d", &num);
        printf("%d\n", num);//输出12345 
        fclose(fp);
    } else {
        printf("无法打开文件\n");
    }
    return 0;
}

3.文本文件与二进制文件

  • 所有文件最终都是二进制的
  • 文本文件是用最简单的方式可以读写的文件
    • more、tail
    • cat
    • vi
  • 二进制文件是需要专门的程序来读写的文件
  • 文本文件的输入输出是格式化可能经过转码的

3.1 Unix与Windows对文件的选取

  • Unix喜欢用文本文件做数据存储和程序配置
    • 交互式终端的出现使得人们喜欢用文本和计算机交互
    • Unix的shell提供了一些读写文本的小程序
  • Windows喜欢用二进制文件
    • PC刚开始的时候能力有限,DOS的能力更有限,二进制更接近底层

3.2 优缺点

文本:

  • 优势:方便人类读写,而且跨平台
  • 劣势:程序输入输出要经过格式化,开销大

二进制

  • 优势:程序读写快
  • 劣势:人类读写困难,不能跨平台
    • int的大小不一致,大小端的问题

3.3 文件的应用

  • 配置
    • Unix用文本,Windows用注册表
  • 数据
    • 稍微有点量的数据都要存储到数据库中
  • 媒体
    • 媒体只能是二进制的
  • 现实情况,程序通过第三方库来读写文件,很少直接读写二进制文件

3.4 二进制文件的读写

  • size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
  • size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
  • 返回的是成功读写的字节数
  • FILE指针是最后一个参数
  • nitem是用来说明这次读写几个结构变量,二进制文件的读写一般都是通过一个结构变量的操作来进行的

student.h

#ifndef _STUDENT_H_
#define _STUDENT_H_


typedef struct _student{
    char name[20];
    int gender;
    int age;
} Student;

#endif

main.c

#include <stdio.h>
#include "student.h"

void inputList(Student aStu[], int number);
int save(Student aStu[], int number);

int main(int argc, char *argv[]) {

    int number = 0;
    printf("请输入学生的数量:");
    scanf("%d", &number);
    Student aStu[number];

    inputList(aStu, number);

    if(save(aStu, number)){
        printf("保存成功\n");
    } else {
        printf("保存失败\n");
    }

    return 0;
}

void inputList(Student aStu[], int number)
{
    char format[20];
    sprintf(format, "%%%ds", 19);

    int i;
    for(i = 0; i < number; i++){
        printf("第%d个学生:\n", i);

        printf("\t姓名:");
        scanf(format, aStu[i].name);

        printf("\t性别(0-男,1-女,2-其他)");
        scanf("%d", &aStu[i].gender);

        printf("\t年龄:");
        scanf("%d", &aStu[i].age);
    }
}



int save(Student aStu[], int number)
{
    int ret = -1;
    FILE *fp = fopen("Student.data", "w");
    if(fp){
        ret = fwrite(aStu, sizeof(Student), number, fp);
        fclose(fp);
    }
    return ret == number;
}

这里写图片描述

student.data中保存的是二进制

这里写图片描述

3.5 在文件中定位

  • long ftell(FILE *stream);
  • int fseek(FILE *stream, long offset, int whence);
    • whence:
      • SEEK_SET:从头开始
      • SEEK_CUR:从当前位置开始
      • SEEK_END:从尾开始

student.h

int index = 0;

main.c

#include <stdio.h>
#include "student.h"

void read(FILE *fp, int index);

int main(int argc, char *argv[]) {

    FILE *fp = fopen("student.data", "r");
    if(fp){
        fseek(fp, 0L, SEEK_END);

        long size = ftell(fp);
        int number = size / sizeof(Student);
        printf("有%d个数据,你要看第几个:", number);

        int index = 0;
        scanf("%d", &index);

        read(fp, index - 1);

        fclose(fp);

    }

    return 0;
}

void read(FILE *fp, int index)
{
    fseek(fp, index*sizeof(Student), SEEK_SET);

    Student stu;
    if(fread(&stu, sizeof(Student), 1, fp) == 1){
        printf("第%d个学生:", index + 1);
        printf("\t姓名:%s\n", stu.name);
        printf("\t性别:");
        switch(stu.gender){
            case 0:
                printf("男\n"); 
                break;
            case 1:
                printf("女\n");
                break;
            case 2:
                printf("其他\n");
                break;
        }
        printf("\t年龄:%d\n", stu.age);
    } 
}

这里写图片描述

tips

  • student.data这种二进制文件不具有可移植性
    • 在int位32位的机器上写成的数据文件 不能直接在int为64位的机器上正确读写
  • 更好的方案是用文本
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值