C语言readdat函数如何正确读取文件数据?

99ANYc3cd6
预计阅读时长 20 分钟
位置: 首页 C语言 正文

readdat 并不是 C 语言标准库中的一个函数,它更像是一个自定义函数的名称,通常出现在教学、练习或者特定项目中,其目的是从一个文件中读取数据。

c语言 readdat
(图片来源网络,侵删)

readdat 的具体实现取决于你想要读取的数据格式(比如是纯文本、CSV、二进制等)和数据结构(比如是整数、浮点数、字符串还是结构体)。

下面我将通过几个最常见的场景,为你展示如何实现一个名为 readdat 的函数。


从文本文件中读取整数

假设我们有一个名为 data.txt 的文件,内容如下:

10
20
30
40
50

我们的目标是把这些整数读入一个数组中。

c语言 readdat
(图片来源网络,侵删)

readdat.h (头文件)

#ifndef READDAT_H
#define READDAT_H
// 函数声明
// 从文件名读取整数到数组,并返回读取的个数
int readdat(const char* filename, int* arr, int max_size);
#endif // READDAT_H

readdat.c (函数实现)

#include <stdio.h>
#include "readdat.h"
int readdat(const char* filename, int* arr, int max_size) {
    FILE* fp = fopen(filename, "r"); // 以只读模式打开文件
    if (fp == NULL) {
        perror("Error opening file"); // 打印错误信息
        return -1; // 返回-1表示打开文件失败
    }
    int count = 0;
    int num;
    // 循环读取文件中的整数,直到文件结束或数组已满
    while (fscanf(fp, "%d", &num) == 1 && count < max_size) {
        arr[count] = num;
        count++;
    }
    fclose(fp); // 关闭文件
    return count; // 返回成功读取的整数个数
}

main.c (主程序)

#include <stdio.h>
#include "readdat.h"
#define MAX_NUMBERS 100
int main() {
    int numbers[MAX_NUMBERS];
    const char* filename = "data.txt";
    int count = readdat(filename, numbers, MAX_NUMBERS);
    if (count >= 0) {
        printf("Successfully read %d numbers from %s:\n", count, filename);
        for (int i = 0; i < count; i++) {
            printf("%d ", numbers[i]);
        }
        printf("\n");
    } else {
        printf("Failed to read data from file.\n");
    }
    return 0;
}

编译和运行:

gcc main.c readdat.c -o myprogram
./myprogram

输出:

Successfully read 5 numbers from data.txt:
10 20 30 40 50 

从文本文件中读取结构体

假设我们有一个 students.dat 文件,每行是一个学生的信息(ID, 姓名, 成绩),格式如下:

101 ZhangSan 88.5
102 LiSi 92.0
103 WangWu 76.5

我们要将这些数据读入一个结构体数组。

c语言 readdat
(图片来源网络,侵删)

定义结构体

// student.h
#ifndef STUDENT_H
#define STUDENT_H
typedef struct {
    int id;
    char name[50];
    float score;
} Student;
#endif // STUDENT_H

实现 readdat 函数

// readdat_students.c
#include <stdio.h>
#include <string.h>
#include "student.h"
// 从文件中读取学生数据到结构体数组
int readdat(const char* filename, Student* students, int max_size) {
    FILE* fp = fopen(filename, "r");
    if (fp == NULL) {
        perror("Error opening file");
        return -1;
    }
    int count = 0;
    // 使用fgets和sscanf来处理可能包含空格的姓名
    char line[100]; // 假设一行数据不超过100个字符
    while (fgets(line, sizeof(line), fp) != NULL && count < max_size) {
        // 去除行尾的换行符
        line[strcspn(line, "\n")] = 0;
        // 从字符串中解析数据
        if (sscanf(line, "%d %49s %f", &students[count].id, students[count].name, &students[count].score) == 3) {
            count++;
        }
    }
    fclose(fp);
    return count;
}

主程序

// main_students.c
#include <stdio.h>
#include "student.h"
#include "readdat_students.c" // 包含实现
#define MAX_STUDENTS 100
int main() {
    Student students[MAX_STUDENTS];
    const char* filename = "students.dat";
    int count = readdat(filename, students, MAX_STUDENTS);
    if (count >= 0) {
        printf("Successfully read %d students from %s:\n", count, filename);
        for (int i = 0; i < count; i++) {
            printf("ID: %d, Name: %s, Score: %.1f\n", students[i].id, students[i].name, students[i].score);
        }
    } else {
        printf("Failed to read data from file.\n");
    }
    return 0;
}

编译和运行:

gcc main_students.c readdat_students.c -o student_program
./student_program

输出:

Successfully read 3 students from students.dat:
ID: 101, Name: ZhangSan, Score: 88.5
ID: 102, Name: LiSi, Score: 92.0
ID: 103, Name: WangWu, Score: 76.5

从二进制文件中读取结构体

如果数据是二进制格式,读写效率更高,且格式不依赖于文本表示,我们假设已经有一个 students.bin 文件,里面直接存放了 Student 结构体的二进制数据。

readdat_binary.c (二进制版本实现)

#include <stdio.h>
#include "student.h"
// 从二进制文件中读取学生数据
int readdat(const char* filename, Student* students, int max_size) {
    FILE* fp = fopen(filename, "rb"); // "rb" 表示以二进制只读模式打开
    if (fp == NULL) {
        perror("Error opening binary file");
        return -1;
    }
    int count = 0;
    // 使用fread直接从文件中读取一块内存数据
    while (count < max_size && fread(&students[count], sizeof(Student), 1, fp) == 1) {
        count++;
    }
    fclose(fp);
    return count;
}

注意:

  • fopen 模式: 使用 "rb" (binary read)。
  • fread 函数: fread(void* ptr, size_t size, size_t count, FILE* stream)
    • ptr: 指向存储读取数据的内存地址(这里是 &students[count])。
    • size: 每个数据块的大小(这里是 sizeof(Student))。
    • count: 要读取多少个这样的数据块(这里是 1,一次读一个学生)。
    • stream: 文件指针。
  • 这种方式比文本方式快得多,但文件的可读性差,并且存在字节序(大端/小端)问题,在不同架构的计算机间直接传输二进制文件可能会出错。

总结与关键点

  1. readdat 是自定义函数: 它不是 C 标准库的一部分,你需要自己定义和实现它。
  2. 核心是文件操作: C 语言通过 FILE* 指针和 <stdio.h> 中的函数(fopen, fscanf, fgets, fread, fclose 等)来操作文件。
  3. 打开模式很重要:
    • "r": 文本只读。
    • "rb": 二进制只读。
    • "w": 文本写入(会覆盖)。
    • "wb": 二进制写入(会覆盖)。
  4. 选择合适的读取函数:
    • 格式化文本: fscanf (类似 scanf)。
    • 行文本: fgets (读取一行)。
    • 二进制数据: fread (直接读取内存块)。
  5. 错误处理: 始终检查 fopen 是否返回 NULL,以处理文件不存在或无权限等情况,使用 perror 可以打印有意义的错误信息。
  6. 关闭文件: 使用完文件后,一定要用 fclose 关闭它,释放系统资源。

希望这些例子能帮助你理解如何在 C 语言中实现一个 readdat 函数!你可以根据你的具体需求,修改这些示例来适应你的数据格式和程序结构。

-- 展开阅读全文 --
头像
stlength函数如何计算字符串长度?
« 上一篇 04-16
织梦导航为何突然变成两排了?
下一篇 » 04-16

相关文章

取消
微信二维码
支付宝二维码

目录[+]