谭浩强C语言程序设计(6)文件 10章

发布于:2025-03-03 ⋅ 阅读:(96) ⋅ 点赞:(0)

1、打开文本文件并读取一个字符

桌面上新建文件num.txt。内容为123

#include <cstdio>   // 引入标准输入输出库
#include <cstdlib>  // 引入标准库,包含 exit 函数

int main() {
    FILE* fp;         // 声明一个文件指针,用于操作文件
    char c;           // 声明一个字符变量,用于存储从文件读取的字符

    // 打开名为 "D:\\deskTop\\num.txt" 的文件,权限为只读模式("r")
    fp = fopen("D:\\deskTop\\num.txt", "r");

    // 如果文件打开失败(返回 NULL),说明路径不存在或文件无法访问
    if (fp == NULL) {
        printf("error!"); // 打印错误信息
        exit(0);          // 退出程序,返回值 0 表示正常退出
                          // 建议改为 exit(1) 表示错误退出
    }

    // 使用 fgetc 函数从文件中读取一个字符
    // fgetc 返回读取的字符,文件结束(EOF)时返回 EOF
    c = fgetc(fp);

    // 打印读取的字符
    printf("%c\n", c); // 使用 printf 输出字符

    // 关闭文件,释放文件指针占用的资源
    fclose(fp);

    return 0; // 程序正常结束,返回 0
}

 2、读取文件的全部内容

#include <cstdio>   // 引入标准输入输出库
#include <cstdlib>  // 引入标准库,包含 exit 函数

int main() {
    FILE* fp;         // 声明一个文件指针,用于操作文件
    int c;            // 声明一个整型变量,用于存储从文件读取的字符(包括 EOF)

    // 打开名为 "D:\\deskTop\\num.txt" 的文件,权限为只读模式("r")
    fp = fopen("D:\\deskTop\\num.txt", "r");

    // 如果文件打开失败(返回 NULL),说明路径不存在或文件不可访问
    if (fp == NULL) {
        printf("error!\n"); // 打印错误信息,并添加换行符使输出整齐
        exit(1);            // 退出程序,返回值 1 表示错误退出
    }

    // 使用 fgetc 函数逐个字符读取文件
    // 当 fgetc 返回 EOF 时,表示到达文件末尾或发生错误
    while ((c = fgetc(fp)) != EOF) {
        putchar(c); // 输出当前读取的字符到标准输出(屏幕)
    }

    // 关闭文件,释放文件指针占用的资源
    fclose(fp);

    return 0; // 程序正常结束,返回值为 0
}

3、打开文件并写入字符 

#include <cstdio>   // 引入标准输入输出库
#include <cstdlib>  // 引入标准库,包含 exit 函数

int main() {
    FILE* fp;         // 声明一个文件指针,用于操作文件
    int c;            // 声明一个整型变量,用于存储字符(包括 EOF)

    // 打开名为 "D:\\deskTop\\num.txt" 的文件,权限为写入模式("w")
    fp = fopen("D:\\deskTop\\num.txt", "w");

    // 如果文件打开失败(返回 NULL),说明路径不存在或文件不可访问
    if (fp == NULL) {
        printf("error!\n"); // 打印错误信息,并添加换行符使输出整齐
        exit(1);            // 退出程序,返回值 1 表示错误退出
    }

    // 向文件写入一个字符 '2'(ASCII 码 50 对应字符 '2')
    fputc(50, fp);

    // 关闭文件,释放文件指针占用的资源
    fclose(fp);

    return 0; // 程序正常结束,返回值为 0
}

  • 文件打开模式 "w"

    • 以写入模式打开文件。如果文件不存在,会创建一个新文件;如果文件存在,会清空文件内容。

4、 输入字符串到文件直到输入#为止

#include <cstdio>   // 引入标准输入输出库
#include <cstdlib>  // 引入标准库,包含 exit 函数
#define fileName "D:\\deskTop\\num.txt"  // 定义文件路径常量

int main() {
    FILE* fp;         // 声明一个文件指针,用于操作文件
    char c;           // 声明一个字符变量,用于存储从键盘输入的字符

    // 打开文件 "D:\\deskTop\\num.txt",以写入模式("w")打开
    fp = fopen(fileName, "w");

    // 如果文件打开失败(返回 NULL),说明路径不存在或文件不可访问
    if (fp == NULL) {
        printf("error!\n"); // 打印错误信息,并添加换行符使输出整齐
        exit(1);            // 退出程序,返回值 1 表示错误退出
    }

    printf("input the string:"); // 提示用户输入字符串

    // 从键盘逐个读取字符,直到输入 '#' 为止
    c = getchar();  // 读取第一个字符
    while (c != '#') {
        fputc(c, fp); // 将字符写入文件
        c = getchar(); // 继续读取下一个字符
    }

    // 关闭文件,释放文件指针占用的资源
    fclose(fp);

    return 0; // 程序正常结束,返回值为 0
}

 5、将一个文件的内容复制到另一个文件

#include <cstdio>   // 引入标准输入输出库
#include <cstdlib>  // 引入标准库,包含 exit 函数
#define fileIN "D:\\deskTop\\in.txt"   // 定义输入文件路径常量
#define fileOUT "D:\\deskTop\\out.txt" // 定义输出文件路径常量

int main() {
    FILE* fin;   // 声明用于输入文件的文件指针
    FILE* fout;  // 声明用于输出文件的文件指针
    char c;       // 声明一个字符变量,用于存储读取的字符

    // 打开文件:以读取模式打开输出文件,以写入模式打开输入文件
    fout = fopen(fileOUT, "r"); // 输出文件用于读取
    fin = fopen(fileIN, "w");   // 输入文件用于写入

    // 检查文件是否成功打开
    if (fout == NULL || fin == NULL) {
        printf("out.txt or in.txt is not exist!\n"); // 打印错误信息
        exit(-1);                                    // 退出程序,返回值 -1 表示错误
    }

    // 从输出文件读取字符,并写入到输入文件
    c = fgetc(fout); // 从输入文件(fout,实际上是 output 文件)读取第一个字符
    while (c != EOF) { // 如果未到达文件末尾(EOF)
        fputc(c, fin); // 将字符写入到输出文件(fin,实际上是 input 文件)
        c = fgetc(fout); // 继续读取下一个字符
    }

    // 关闭文件
    fclose(fin);   // 关闭输入文件
    fclose(fout);   // 关闭输出文件

    return 0; // 程序正常结束,返回值为 0
}

6、 fgetc读取多行字符

#include <cstdio>
#include <cstdlib>
#define fileOUT "D:\\deskTop\\out.txt"

int main() {
    FILE * fout;
    char c;
    fout = fopen(fileOUT,"r");
    if (fout == NULL){
        printf("error");
        exit(-1);
    }
    c = fgetc(fout);
    while (c != EOF){
        putchar(c);
        c = fgetc(fout);
    }
    fclose(fout);
}

7、fgets读取一整行的内容

#include <cstdio>   // 引入标准输入输出库
#include <cstdlib>  // 引入标准库,包含 exit 函数
#define fileOUT "D:\\deskTop\\out.txt"  // 定义文件路径常量

int main() {
    FILE * fout;    // 声明一个文件指针,用于操作文件
    char c[50];      // 声明一个字符数组,用于存储从文件读取的字符串,大小为 50

    // 以只读模式 ("r") 打开文件 "D:\\deskTop\\out.txt"
    fout = fopen(fileOUT, "r");

    // 检查文件是否成功打开
    if (fout == NULL) {
        printf("error"); // 打印错误信息
        exit(-1);        // 退出程序,返回值 -1 表示错误
    }

    // 使用 fgets 函数从文件中读取一行内容
    // 参数说明:
    // - c: 存储读取内容的字符数组
    // - 50: 指定读取的字符数(最多读取 49 个字符,最后一个位置用于存储空字符 \0)
    // - fout: 文件指针
    fgets(c, 50, fout);

    // 打印读取的内容到控制台
    puts(c);

    // 关闭文件
    fclose(fout);

    return 0; // 程序正常结束,返回值为 0
}

fgets 函数

  • 从文件中读取一行内容(以换行符 \n 或文件末尾 EOF 为准)。

puts 函数

  • 将字符串 c 输出到标准输出(屏幕)。

  • 会在字符串末尾自动添加换行符 \n

8、fgets读取全部的内容

#include <cstdio>   // 引入标准输入输出库
#include <cstdlib>  // 引入标准库,包含 exit 函数
#define fileOUT "D:\\deskTop\\out.txt"  // 定义文件路径常量

int main() {
    FILE * fout;    // 声明一个文件指针,用于操作文件
    char c[50];      // 声明一个字符数组,用于存储从文件读取的字符串,大小为 50

    // 以只读模式 ("r") 打开文件 "D:\\deskTop\\out.txt"
    fout = fopen(fileOUT, "r");

    // 检查文件是否成功打开
    if (fout == NULL) {
        printf("error"); // 打印错误信息
        exit(-1);        // 退出程序,返回值 -1 表示错误
    }

    // 使用循环逐行读取文件内容并打印
    while (fgets(c, 50, fout)) { // 如果 fgets 成功读取一行内容
        printf("%s", c);          // 打印读取到的内容
    }

    // 关闭文件
    fclose(fout);

    return 0; // 程序正常结束,返回值为 0
}

  • while (fgets(c, 50, fout)) 是一种惯用的写法,用于逐行读取文件内容。

9、读取文件中的若干字符串,对字母进行大小排序,将排序好的字符串再保存到文件

#include <cstdio>   // 引入标准输入输出库
#include <cstdlib>  // 引入标准库函数,如 exit()
#include <cstring>  // 引入字符串操作函数,如 strcpy(), stricmp()

#define fileOUT "D:\\deskTop\\out.txt"  // 定义文件路径宏,存储目标文件路径

// 二分插入排序函数,对字符串数组进行排序
void sort(char (*p)[20], int n) {
    int high, mid, low;  // 定义二分查找的变量
    char temp[20];       // 临时变量,用于存储当前待插入的字符串

    // 从第二个元素开始,逐个插入到已排序的部分
    for (int i = 1; i < n; ++i) {
        strcpy(temp, p[i]);  // 保存当前待插入的字符串
        low = 0;             // 初始化查找范围的起点
        high = i - 1;        // 初始化查找范围的终点

        // 二分查找插入位置
        while (low <= high) {
            mid = (low + high) / 2;  // 计算中间位置
            if (stricmp(temp, p[mid]) > 0) {  // 如果待插入字符串大于中间位置的字符串
                low = mid + 1;  // 在右半部分继续查找
            } else {
                high = mid - 1;  // 在左半部分继续查找
            }
        }

        // 将插入位置之后的元素向后移动
        for (int j = i - 1; j >= low; --j) {
            strcpy(p[j + 1], p[j]);
        }

        // 将待插入字符串插入到正确位置
        strcpy(p[low], temp);
    }
}

int main() {
    FILE *fout;        // 文件指针,用于文件操作
    char c[3][20];     // 用于存储从文件中读取的字符串数组,最多存储3个长度为20的字符串

    // 打开文件以读取数据
    fout = fopen(fileOUT, "r");  // 以只读模式打开文件

    // 检查文件是否成功打开
    if (fout == NULL) {
        perror("Error opening file");  // 输出错误信息
        exit(EXIT_FAILURE);  // 退出程序
    }

    // 从文件中读取数据到数组 c 中
    for (int i = 0; i < 3; ++i) {
        fgets(c[i], 20, fout);  // 读取一行字符串,最多读取 19 个字符
    }

    // 关闭文件
    fclose(fout);

    // 调用排序函数对数组 c 进行排序
    sort(c, 3);

    // 打开文件以写入排序后的数据
    fout = fopen(fileOUT, "w");  // 以写入模式打开文件

    // 将排序后的数据写入文件
    for (int i = 0; i < 3; ++i) {
        fputs(c[i], fout);  // 将字符串写入文件
    }

    // 关闭文件
    fclose(fout);

    return 0;  // 程序正常结束
}

 10、fscanf读取文件的内容

#include <cstdio>    // 引入标准输入输出库
#include <cstdlib>   // 引入标准库函数,如 exit()

#define fileOUT "D:\\deskTop\\out.txt"  // 定义文件路径宏,存储目标文件路径

int main() {
    FILE *fout;  // 文件指针,用于文件操作
    int i;       // 用于存储从文件中读取的整数
    float f;     // 用于存储从文件中读取的浮点数

    // 打开文件以读取数据
    fout = fopen(fileOUT, "r");  // 以只读模式打开文件

    // 检查文件是否成功打开
    if (fout == NULL) {
        perror("Error opening file");  // 输出错误信息
        exit(EXIT_FAILURE);  // 终止程序
    }

    // 从文件中读取整数和浮点数
    fscanf(fout, "%d", &i);  // 读取文件中的整数
    fscanf(fout, "%f", &f);  // 读取文件中的浮点数

    // 关闭文件
    fclose(fout);

    // 打印读取的整数和浮点数
    printf("%d\n", i);  // 打印整数
    printf("%f", f);    // 打印浮点数

    return 0;  // 程序正常结束
}

 

11、使用fprintf写数据到文件 

    fout = fopen(fileOUT,"w");
    fprintf(fout,"%d",12);
    fprintf(fout,"%s","哈哈哈");
    fprintf(fout,"%f",3.14);

    fclose(fout);

 12、使用fread,fwrite读写数据到文件

#include <cstdio>    // 包含标准输入输出函数头文件
#include <cstdlib>   // 包含标准库函数头文件

#define fileName "D:\\deskTop\\out.dat"  // 定义目标文件路径(用户需要确保该路径存在)
#define N 3                               // 定义学生信息的数量

// 定义学生结构体
struct student {
    int num;     // 学号
    char name[20]; // 姓名(最多19个字符,实际存储需要额外的空字符)
} stu[N];          // 创建学生结构体数组

int main() {
    // 输入三个学生的信息
    for (int i = 0; i < N; ++i) {
        printf("Input the %d info (num, name):\n", i + 1); // 提示用户输入第i+1个学生的信息
        // 使用 %19s 限制名字的长度,避免缓冲区溢出
        if (scanf("%d %19s", &stu[i].num, stu[i].name) != 2) { // 读取学号和名字
            printf("Input error!\n"); // 输入异常提示
            return -1;                // 退出程序
        }
    }

    // 写入到文件
    FILE *file; // 定义文件指针
    file = fopen(fileName, "wb"); // 以二进制写模式打开文件
    if (file == NULL) { // 检查文件是否成功打开
        printf("Failed to open file %s!\n", fileName); // 打开失败提示
        return -1;                                  // 退出程序
    }

    for (int i = 0; i < N; ++i) { // 遍历学生数组
        // 将每个学生结构体写入文件
        if (fwrite(&stu[i], sizeof(struct student), 1, file) != 1) {
            printf("Failed to write student %d to file!\n", i + 1); // 写入失败提示
        }
    }

    fclose(file); // 关闭文件

    printf("Three students' information has been written to file %s successfully!\n", fileName); // 写入成功提示

    // 读取文件验证是不是写入成功了
    file = fopen(fileName, "rb"); // 以二进制读模式打开文件
    for (int i = 0; i < N; ++i) { // 遍历学生数组
        fread(&stu[i], sizeof(struct student), 1, file); // 从文件中读取每个学生结构体
        printf("%d %s\n", stu[i].num, stu[i].name); // 输出读取的学生信息
    }

    return 0; // 程序结束,返回退出码0(正常退出)
}

size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);

  • ptr:指向要写入的数据的指针。
  • size:每个数据项的大小(以字节为单位)。
  • count:要写入的数据项的个数。
  • stream:指向 FILE 对象的指针,表示要写入的文件。
if (fwrite(&stu[i], sizeof(struct student), 1, file) != 1) { printf("Failed to write student %d to file!\n", i + 1); } 
  • &stu[i]:指向 stu 数组中第 i 个 student 结构体的指针。
  • sizeof(struct student):每个 student 结构体的大小。
  • 1:写入一个 student 结构体。
  • file:指向要写入的文件的指针。


 
size_t fread(void *ptr, size_t size, size_t count, FILE *stream); 
  • ptr:指向存储读取数据的内存块的指针。
  • size:每个数据项的大小(以字节为单位)。
  • count:要读取的数据项的个数。
  • stream:指向 FILE 对象的指针,表示要读取的文件。

 
fread(&stu[i], sizeof(struct student), 1, file); 
  • &stu[i]:指向 stu 数组中第 i 个 student 结构体的指针。
  • sizeof(struct student):每个 student 结构体的大小。
  • 1:读取一个 student 结构体。
  • file:指向要读取的文件的指针。

13、rewind函数实现读取文件信息,第一次将文件信息输出,第二次将文件复制到另一个文件

#include <cstdio>
#include <cstdlib>

#define fileName1 "D:\\deskTop\\out.txt"
#define fileName2 "D:\\deskTop\\in.txt"

int main() {
    FILE *fp1, *fp2;
    int ch;

    // 打开输入文件
    fp1 = fopen(fileName1, "rb"); // 以二进制模式打开
    if (fp1 == NULL) {
        perror("Failed to open input file");
        return -1;
    }

    // 打开输出文件
    fp2 = fopen(fileName2, "wb"); // 以二进制模式打开
    if (fp2 == NULL) {
        perror("Failed to open output file");
        fclose(fp1);
        return -1;
    }

    // 读取并输出到控制台
    printf("Contents of %s:\n", fileName1);
    while ((ch = fgetc(fp1)) != EOF) {
        putchar(ch); // 输出到控制台
        fputc(ch, fp2); // 复制到输出文件
    }
    putchar('\n');

    // 关闭文件
    if (fclose(fp1) != 0 || fclose(fp2) != 0) {
        perror("Failed to close files");
    }

    printf("Files closed successfully.\n");
    return 0;
}