【重拾C语言】十一、外部数据组织——文件

2024-07-30 08:53:25 浏览数 (1)

前言

C语言中的外部数据组织涉及文件的处理。文件是一种用于存储和读取数据的数据结构。在C语言中,我们可以使用文件来保存和管理大量的数据,包括文本文件和二进制文件。

十一、外部数据组织——文件

11.1 重新考虑户籍管理问题——文件

11.2 文件概述

文件是存储在外部介质上的一组相关数据。它可以是文本文件,包含可读的字符数据,也可以是二进制文件,包含不可读的二进制数据。

11.2.1 文件分类

主要有文本文件和二进制文件两种类型。文本文件是由字符组成的文件,可以使用文本编辑器打开查看和编辑。二进制文件是由二进制数据组成的文件,不可直接查看和编辑。

11.2.2 文件指针、标记及文件操作

文件指针是一个指向文件位置的指针,用于在文件中定位和操作数据。文件标记是用于标识文件中特定位置的标识符。文件操作包括打开文件、关闭文件、读取文件和写入文件等。

11.3 打开、关闭文件

在C语言中,可以使用fopen函数来打开文件,并使用fclose函数来关闭文件。打开文件时,需要指定文件名和打开模式,打开模式可以是读模式、写模式或追加模式等。

代码语言:javascript复制
#include <stdio.h>

int main() {
    FILE *file;
    char *filename = "example.txt";
    char *mode = "r"; // 使用 "r" 模式打开文件(只读模式)

    // 打开文件
    file = fopen(filename, mode);
    if (file == NULL) {
        printf("无法打开文件:%sn", filename);
        return 1;
    }

    // 在这里可以进行读取文件内容的操作

    // 关闭文件
    fclose(file);

    return 0;
}

11.4 I/O操作

11.4.1 字符读写

使用fgetc函数读取一个字符,使用fputc函数写入一个字符。

代码语言:javascript复制
#include <stdio.h>

int main() {
    FILE *file;
    char ch;

    // 打开文件
    file = fopen("example.txt", "r");
    if (file == NULL) {
        printf("无法打开文件n");
        return 1;
    }

    // 逐个字符读取并输出文件内容
    while ((ch = fgetc(file)) != EOF) {
        printf("%c", ch);
    }

    // 关闭文件
    fclose(file);

    return 0;
}
11.4.2 字符串读写

使用fgets函数读取一行字符串,使用fputs函数写入一个字符串。

代码语言:javascript复制
#include <stdio.h>

int main() {
    FILE *file;
    char str[100];

    // 打开文件
    file = fopen("example.txt", "r");
    if (file == NULL) {
        printf("无法打开文件n");
        return 1;
    }

    // 读取一行字符串并输出
    fgets(str, sizeof(str), file);
    printf("%s", str);

    // 关闭文件
    fclose(file);

    return 0;
}
11.4.3 格式化读写

使用fscanf函数按照指定的格式从文件中读取数据,使用fprintf函数按照指定的格式将数据写入文件

代码语言:javascript复制
#include <stdio.h>

int main() {
    FILE *file;
    int num1, num2;
    float num3;

    // 打开文件以供读写
    file = fopen("data.txt", "w ");

    if (file == NULL) {
        printf("无法打开文件!n");
        return 1;
    }

    // 向文件中写入数据
    fprintf(file, "%d %d %.2f", 10, 20, 3.14);

    // 将文件指针移动到文件开头
    fseek(file, 0, SEEK_SET);

    // 从文件中读取数据
    fscanf(file, "%d %d %f", &num1, &num2, &num3);

    // 输出读取的数据
    printf("读取的数据:%d %d %.2fn", num1, num2, num3);

    // 关闭文件
    fclose(file);

    return 0;
}
11.4.4 数据块读写

使用fread函数读取一块数据,使用fwrite函数写入一块数据。

代码语言:javascript复制
#include <stdio.h>

typedef struct {
    int id;
    char name[20];
    float salary;
} Employee;

int main() {
    FILE *file;
    Employee employees[3];

    // 打开文件以供读写
    file = fopen("employees.bin", "wb ");

    if (file == NULL) {
        printf("无法打开文件!n");
        return 1;
    }

    // 写入数据块
    employees[0].id = 1;
    strcpy(employees[0].name, "John");
    employees[0].salary = 5000.0;

    employees[1].id = 2;
    strcpy(employees[1].name, "Alice");
    employees[1].salary = 6000.0;

    employees[2].id = 3;
    strcpy(employees[2].name, "Bob");
    employees[2].salary = 5500.0;

    fwrite(employees, sizeof(Employee), 3, file);

    // 将文件指针移动到文件开头
    fseek(file, 0, SEEK_SET);

    // 读取数据块
    fread(employees, sizeof(Employee), 3, file);

    // 输出读取的数据
    for (int i = 0; i < 3; i  ) {
        printf("员工%d:n", i   1);
        printf("ID:%dn", employees[i].id);
        printf("姓名:%sn", employees[i].name);
        printf("工资:%.2fn", employees[i].salary);
        printf("n");
    }

    // 关闭文件
    fclose(file);

    return 0;
}
11.4.5 文件定位

文件定位是指在文件中移动文件指针的操作。在C语言中,可以使用fseek()函数进行文件定位。fseek()函数的原型如下:

代码语言:javascript复制
int fseek(FILE *stream, long offset, int whence);

其中,stream是一个指向FILE结构的指针,表示要进行定位的文件;offset表示要移动的字节数或记录数;whence表示起始位置,可以是以下常量之一:

  • SEEK_SET:从文件开头开始计算偏移量。
  • SEEK_CUR:从当前位置开始计算偏移量。
  • SEEK_END:从文件末尾开始计算偏移量。
代码语言:javascript复制
#include <stdio.h>

int main() {
    FILE *file;
    char ch;

    // 打开文件供读取
    file = fopen("data.txt", "r");

    if (file == NULL) {
        printf("无法打开文件!n");
        return 1;
    }

    // 将文件指针移动到文件末尾
    fseek(file, 0, SEEK_END);

    // 获取文件大小(字节数)
    long size = ftell(file);

    // 从文件末尾向前读取数据
    for (long i = size - 1; i >= 0; i--) {
        fseek(file, i, SEEK_SET);
        ch = fgetc(file);
        printf("%c", ch);
    }

    // 关闭文件
    fclose(file);

    return 0;
}

首先使用fopen()函数打开一个名为"data.txt"的文件,使用"r"模式表示只读取文件内容。然后使用fseek()函数将文件指针移动到文件末尾,使用ftell()函数获取文件大小(字节数)。接下来,使用循环从文件末尾向前读取数据,每次将文件指针移动到指定位置并使用fgetc()函数读取一个字符,并将其输出到控制台。最后使用fclose()函数关闭文件。

11.5 与操作系统文件联系——程序参数

11.5.1 程序参数

程序参数是指在执行程序时通过命令行传递给程序的额外信息。通过使用程序参数,可以在程序运行时向程序传递不同的数据或配置选项,从而实现更灵活的程序行为。与操作系统文件的联系在于,程序参数可以包含文件路径或文件名等信息,以便程序能够读取或操作指定的文件。例如,用户可以通过命令行输入文件路径作为程序参数,然后程序可以使用该路径打开文件并进行相应的操作。

在C语言中,程序参数可以通过main()函数的参数获取。main()函数的标准形式为:

代码语言:javascript复制
int main(int argc, char *argv[])

其中,argc表示命令行参数的数量,argv是一个指向指针的指针,用于存储命令行参数的字符串数组。argv[0]存储程序的名称,argv[1]argv[2]等依次存储传递给程序的参数字符串。

代码语言:javascript复制
#include <stdio.h>

int main(int argc, char *argv[]) {
    if (argc < 2) {
        printf("请指定文件路径作为参数!n");
        return 1;
    }

    FILE *file;
    char ch;

    // 打开指定的文件供读取
    file = fopen(argv[1], "r");

    if (file == NULL) {
        printf("无法打开文件:%sn", argv[1]);
        return 1;
    }

    // 读取文件内容并输出到控制台
    while ((ch = fgetc(file)) != EOF) {
        printf("%c", ch);
    }

    // 关闭文件
    fclose(file);

    return 0;
}
11.5.2 健壮性与exit函数

健壮性是指程序的强壮性和容错能力,即在面对异常或错误情况时,程序能够正常运行或适当地处理错误,而不会崩溃或产生无法预料的结果。

在C语言中,可以使用exit()函数来终止程序的执行并返回到操作系统。exit()函数的原型:

代码语言:javascript复制
void exit(int status);

其中,status表示程序的退出状态码,通常用于向操作系统传递程序的执行结果或状态信息。一般约定,状态码为0表示程序执行成功,非零值表示程序执行失败或出现错误。

在编写健壮的程序时,可以根据具体情况使用exit()函数来处理错误或异常。例如,当程序无法打开所需的文件时,可以使用exit()函数终止程序的执行,并返回一个非零的状态码,以便通知操作系统程序执行失败。

代码语言:javascript复制
#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *file;

    // 打开文件供读取
    file = fopen("data.txt", "r");

    if (file == NULL) {
        printf("无法打开文件!n");
        exit(1);  // 终止程序执行并返回状态码1
    }

    // 读取文件内容并输出到控制台
    char ch;
    while ((ch = fgetc(file)) != EOF) {
        printf("%c", ch);
    }

    // 关闭文件
    fclose(file);

    return 0;
}

我们尝试打开一个名为"data.txt"的文件供读取。如果文件打开失败(即fileNULL),则输出错误消息并使用exit(1)终止程序的执行,并返回状态码1。这个状态码可以表示执行失败的情况。

通过使用exit()函数,可以在程序遇到无法继续执行的错误或异常情况时,及时终止程序的执行,避免产生不确定的结果或进一步的错误。

11.5.3 给定程序参数

可以通过命令行参数或其他方式将参数传递给程序,然后程序可以根据参数进行相应的操作。

待完善

11.6 程序设计实例

0 人点赞