C语言之文件操作一

283 阅读3分钟

按字符读取文件

int main() {
    // 获取文件操作指针
    // 注意,在MAC下,写相对路径时需要作工程配置
    // 请参考https://blog.csdn.net/djw931017/article/details/87832073
    FILE *fp = fopen("./a.txt", "r");
    if (!fp) {
        printf("%s\n", "文件打开失败");
        return EXIT_FAILURE;
    }
    // 按每个字符读取,文件字符结束标志: EOF,值为-1
    int ch;
    while ((ch = fgetc(fp)) != EOF) {
        printf("%c", ch);
    }
    fclose(fp);
    return EXIT_SUCCESS;
}

按字符写入文件

int main() {
    // 以这种模式写入文件,若文件不存在,会自动创建
    // 若文件存在,则会覆盖里面的内容
    FILE *fp = fopen("./a.txt", "w");
    if (!fp) {
        printf("%s\n", "文件写入失败");
        return EXIT_FAILURE;
    }
    // 写一个字符
    putc('A', fp);
    fclose(fp);
    return EXIT_SUCCESS;
}

向文件追加内容

int main() {
    FILE *fp = fopen("./a.txt", "a");
    if (!fp) {
        printf("%s\n", "文件写入失败");
        return EXIT_FAILURE;
    }
    // 向文件里面追加一个字符
    fputc('B', fp);
    fclose(fp);
    return EXIT_SUCCESS;
}

按行读取文件内容

int main() {
    // r+表示可读可写模式
    FILE *fp = fopen("./a.txt", "w");
    if (!fp)return EXIT_FAILURE;
    //向文件写入字符串
    fputs("今天是个好日子\n", fp);
    fputs("今天天气不错\n", fp);
    fputs("今天你好漂亮\n", fp);
    fflush(fp);
    fclose(fp);

    FILE *readFile = fopen("./a.txt", "r");
    // 将文件读取到内存中,需要在堆内存中申请一块缓存区
    char *buf = malloc(sizeof(char) * 1024);// 缓存区大小为1KB
    // 按每一行读取,文件流结束标志:feof
    while (feof(readFile) == 0) {
        //每一次读取一行数据,需把上一次读取的数据清空,
        // 避免影响本次的数据
        memset(buf, 0, 1024);
        fgets(buf, 1024, readFile);
        printf("%s", buf);
    }
    if (buf) {
        free(buf);
    }
    fclose(readFile);
    return EXIT_SUCCESS;
}

格式化读写文件

int main() {
    FILE *wf = fopen("./a.txt", "w");
    if (!wf)return EXIT_FAILURE;
    int a = 10, b = 20;
    // 将数据格式化写入文件
    fprintf(wf, "%d+%d=%d\n", a, b, (a + b));
    fclose(wf);

    FILE *rf = fopen("./a.txt", "r");
    if (!rf)return EXIT_FAILURE;
    // 格式化读取文件数据
    int c, d, e;
    fscanf(rf, "%d+%d=%d\n", &c, &d, &e);
    printf("%d+%d=%d\n", c, d, e);
    fclose(rf);
    return EXIT_SUCCESS;
}

练习

  • 四则运算
enum Operator {
    add, minus, multiply, divide
};

struct Calculation {
    int num1;
    int num2;
    char c;
    int result;
};

typedef struct Calculation Calculator;

int main() {
    srand((unsigned int) time(NULL));
    FILE *wf = fopen("./a.txt", "r+");
    if (!wf)return EXIT_FAILURE;
    // 先随机生成100个四则运算表达式并写入到文件中
    int a, b;
    char c;
    char buf[20];
    for (int i = 0; i < 100; i++) {
        switch (rand() % 4) {
            case add:
                c = '+';
                break;
            case minus:
                c = '-';
                break;
            case multiply:
                c = '*';
                break;
            case divide:
                c = '/';
                break;
            default:
                c = '+';
                break;
        }
        a = rand() % 10 + 1;
        b = rand() % 10 + 1;
        memset(buf, 0, 20);
        sprintf(buf, "%d  %c  %d  =\n", a, c, b);
        fputs(buf, wf);
    }
    fclose(wf);
    // 计算文件中表达式的结果,并暂时保存到堆中Calculator结构体中
    Calculator *cal = malloc(sizeof(Calculator) * 100);
    FILE *rf = fopen("./a.txt", "r+");
    if (!rf)return EXIT_FAILURE;
    for (int j = 0; j < 100; j++) {
        fscanf(rf, "%d  %c  %d  =\n", &cal[j].num1, &cal[j].c, &cal[j].num2);
        switch (cal[j].c) {
            case '+':
                cal[j].result = cal[j].num1 + cal[j].num2;
                break;
            case '-':
                cal[j].result = cal[j].num1 - cal[j].num2;
                break;
            case '*':
                cal[j].result = cal[j].num1 * cal[j].num2;
                break;
            case '/':
                cal[j].result = cal[j].num1 / cal[j].num2;
                break;
            default:
                break;
        }
    }
    fclose(rf);
    // 将计算后的结果全部重新写到文件中
    FILE *retFile = fopen("./a.txt", "r+");
    if (!retFile)return EXIT_FAILURE;
    for (int k = 0; k < 100; k++) {
        fprintf(retFile, "%d  %c  %d  =  %d\n", cal[k].num1, cal[k].c, cal[k].num2, cal[k].result);
    }
    fclose(retFile);

    if (cal)free(cal);
    return EXIT_SUCCESS;
}
  • 大数据排序
#define NUM_COUNT 500000
#define NUM_RANGE 1000

int main() {

    // 随机生成NUM_COUNT个1~1000的数字并写入到文件中,然后进行排序
    srand((unsigned int) time(NULL));
    FILE *randomFile = fopen("./a.txt", "w");
    if (!randomFile)return EXIT_FAILURE;
    for (int i = 0; i < NUM_COUNT; ++i) {
        fprintf(randomFile, "%d\n", rand() % NUM_RANGE + 1);
    }
    fclose(randomFile);
    unsigned int start = (unsigned int) time(NULL);
    // 由于数据的范围是1~1000,所以可以用当前数-1就可以放在一个数组的位置
    // 记录每个数出现的次数,然后根据次数写入文件
    FILE *readFile = fopen("./a.txt", "r");
    if (!readFile)return EXIT_FAILURE;
    int arr[NUM_RANGE] = {0};
    int value;
    for (int j = 0; j < NUM_COUNT; j++) {
        fscanf(readFile, "%d\n", &value);
        arr[value - 1]++;
    }
    fclose(readFile);

    FILE *writeFile = fopen("./b.txt", "w");
    if (!writeFile)return EXIT_FAILURE;
    for (int k = 0; k < NUM_RANGE; k++) {
        // arr[k]对应的值为n,就需要写入n次
        for (int i = 0; i < arr[k]; i++) {
            fprintf(writeFile, "%d\n", k + 1);
        }
    }
    fclose(writeFile);
    unsigned int end = (unsigned int) time(NULL);
    printf("排序时间为:%d(s)\n", (end - start));
    return EXIT_SUCCESS;
}