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


    目录

    前言

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

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

    11.2 文件概述

    11.2.1 文件分类

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

    11.3 打开、关闭文件

    11.4 I/O操作

    11.4.1 字符读写

    11.4.2 字符串读写

    11.4.3 格式化读写

    11.4.4 数据块读写

    11.4.5 文件定位

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

    11.5.1 程序参数

    11.5.2 健壮性与exit函数

    11.5.3 给定程序参数

    11.6 程序设计实例


    前言

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

       

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

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

    11.2 文件概述

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

    11.2.1 文件分类

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

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

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

    11.3 打开、关闭文件

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

    1. #include
    2. int main() {
    3. FILE *file;
    4. char *filename = "example.txt";
    5. char *mode = "r"; // 使用 "r" 模式打开文件(只读模式)
    6. // 打开文件
    7. file = fopen(filename, mode);
    8. if (file == NULL) {
    9. printf("无法打开文件:%s\n", filename);
    10. return 1;
    11. }
    12. // 在这里可以进行读取文件内容的操作
    13. // 关闭文件
    14. fclose(file);
    15. return 0;
    16. }

    11.4 I/O操作

    11.4.1 字符读写

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

    1. #include
    2. int main() {
    3. FILE *file;
    4. char ch;
    5. // 打开文件
    6. file = fopen("example.txt", "r");
    7. if (file == NULL) {
    8. printf("无法打开文件\n");
    9. return 1;
    10. }
    11. // 逐个字符读取并输出文件内容
    12. while ((ch = fgetc(file)) != EOF) {
    13. printf("%c", ch);
    14. }
    15. // 关闭文件
    16. fclose(file);
    17. return 0;
    18. }

    11.4.2 字符串读写

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

    1. #include
    2. int main() {
    3. FILE *file;
    4. char str[100];
    5. // 打开文件
    6. file = fopen("example.txt", "r");
    7. if (file == NULL) {
    8. printf("无法打开文件\n");
    9. return 1;
    10. }
    11. // 读取一行字符串并输出
    12. fgets(str, sizeof(str), file);
    13. printf("%s", str);
    14. // 关闭文件
    15. fclose(file);
    16. return 0;
    17. }

    11.4.3 格式化读写

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

    1. #include
    2. int main() {
    3. FILE *file;
    4. int num1, num2;
    5. float num3;
    6. // 打开文件以供读写
    7. file = fopen("data.txt", "w+");
    8. if (file == NULL) {
    9. printf("无法打开文件!\n");
    10. return 1;
    11. }
    12. // 向文件中写入数据
    13. fprintf(file, "%d %d %.2f", 10, 20, 3.14);
    14. // 将文件指针移动到文件开头
    15. fseek(file, 0, SEEK_SET);
    16. // 从文件中读取数据
    17. fscanf(file, "%d %d %f", &num1, &num2, &num3);
    18. // 输出读取的数据
    19. printf("读取的数据:%d %d %.2f\n", num1, num2, num3);
    20. // 关闭文件
    21. fclose(file);
    22. return 0;
    23. }

    11.4.4 数据块读写

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

    1. #include
    2. typedef struct {
    3. int id;
    4. char name[20];
    5. float salary;
    6. } Employee;
    7. int main() {
    8. FILE *file;
    9. Employee employees[3];
    10. // 打开文件以供读写
    11. file = fopen("employees.bin", "wb+");
    12. if (file == NULL) {
    13. printf("无法打开文件!\n");
    14. return 1;
    15. }
    16. // 写入数据块
    17. employees[0].id = 1;
    18. strcpy(employees[0].name, "John");
    19. employees[0].salary = 5000.0;
    20. employees[1].id = 2;
    21. strcpy(employees[1].name, "Alice");
    22. employees[1].salary = 6000.0;
    23. employees[2].id = 3;
    24. strcpy(employees[2].name, "Bob");
    25. employees[2].salary = 5500.0;
    26. fwrite(employees, sizeof(Employee), 3, file);
    27. // 将文件指针移动到文件开头
    28. fseek(file, 0, SEEK_SET);
    29. // 读取数据块
    30. fread(employees, sizeof(Employee), 3, file);
    31. // 输出读取的数据
    32. for (int i = 0; i < 3; i++) {
    33. printf("员工%d:\n", i + 1);
    34. printf("ID:%d\n", employees[i].id);
    35. printf("姓名:%s\n", employees[i].name);
    36. printf("工资:%.2f\n", employees[i].salary);
    37. printf("\n");
    38. }
    39. // 关闭文件
    40. fclose(file);
    41. return 0;
    42. }

    11.4.5 文件定位

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

    int fseek(FILE *stream, long offset, int whence);

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

    • SEEK_SET:从文件开头开始计算偏移量。
    • SEEK_CUR:从当前位置开始计算偏移量。
    • SEEK_END:从文件末尾开始计算偏移量。
    1. #include
    2. int main() {
    3. FILE *file;
    4. char ch;
    5. // 打开文件供读取
    6. file = fopen("data.txt", "r");
    7. if (file == NULL) {
    8. printf("无法打开文件!\n");
    9. return 1;
    10. }
    11. // 将文件指针移动到文件末尾
    12. fseek(file, 0, SEEK_END);
    13. // 获取文件大小(字节数)
    14. long size = ftell(file);
    15. // 从文件末尾向前读取数据
    16. for (long i = size - 1; i >= 0; i--) {
    17. fseek(file, i, SEEK_SET);
    18. ch = fgetc(file);
    19. printf("%c", ch);
    20. }
    21. // 关闭文件
    22. fclose(file);
    23. return 0;
    24. }

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

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

    11.5.1 程序参数

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

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

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

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

    1. #include
    2. int main(int argc, char *argv[]) {
    3. if (argc < 2) {
    4. printf("请指定文件路径作为参数!\n");
    5. return 1;
    6. }
    7. FILE *file;
    8. char ch;
    9. // 打开指定的文件供读取
    10. file = fopen(argv[1], "r");
    11. if (file == NULL) {
    12. printf("无法打开文件:%s\n", argv[1]);
    13. return 1;
    14. }
    15. // 读取文件内容并输出到控制台
    16. while ((ch = fgetc(file)) != EOF) {
    17. printf("%c", ch);
    18. }
    19. // 关闭文件
    20. fclose(file);
    21. return 0;
    22. }

    11.5.2 健壮性与exit函数        

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

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

    void exit(int status);

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

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

    1. #include
    2. #include
    3. int main() {
    4. FILE *file;
    5. // 打开文件供读取
    6. file = fopen("data.txt", "r");
    7. if (file == NULL) {
    8. printf("无法打开文件!\n");
    9. exit(1); // 终止程序执行并返回状态码1
    10. }
    11. // 读取文件内容并输出到控制台
    12. char ch;
    13. while ((ch = fgetc(file)) != EOF) {
    14. printf("%c", ch);
    15. }
    16. // 关闭文件
    17. fclose(file);
    18. return 0;
    19. }

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

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

    11.5.3 给定程序参数

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

    待完善

    11.6 程序设计实例

  • 相关阅读:
    【Python】Python基础
    经典算法题 -- 水仙花数
    初识java——熟悉java代码格式
    领域驱动设计(DDD):从基础代码探讨高内聚低耦合的演进
    20220803NOI模拟赛--考后总结
    Vue - 实现锚点跳转定位到指定页面位置功能 / Anchor 页面添加锚点(仅需一个函数代码超级简洁)
    Ant-Design-Vue全局修改组件默认属性
    基于C++的配置文件解析器/编码器——toml库
    jmeter性能测试,各个指标的预估/测试出来/计算出来,各种关系
    git clone开启云上AI开发
  • 原文地址:https://blog.csdn.net/m0_63834988/article/details/133819650