You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用C语言在指定结构体格式的DAT文件中搜索目标名称

判断指定DAT文件中是否存在目标名称的实现方法

每条记录固定占用32字节,在x86-64架构下对应如下C结构体定义:

typedef struct record {
  unsigned suncents;       // 4字节,存储金额(单位:分)
  unsigned char name_len;  // 1字节,存储名称的有效长度
  char name[27];           // 27字节,存储名称**不包含终止符**,需通过name_len获取有效长度
} record;

数据文件由0条或多条连续记录组成,无固定排序规则。以提供的sample.dat为例,用hexdump -C sample.dat可查看内容:

$ hexdump -C sample.dat 
00000000  86 07 00 00 0e 44 65 6e  6e 69 73 20 52 69 74 63  |.....Dennis Ritc|
00000010  68 69 65 2d 2d 2d 2d 2d  2d 2d 2d 2d 2d 2d 2d 2d  |hie-------------|
00000020  22 01 00 00 0a 41 72 63  68 69 6d 65 64 65 73 2d  |"....Archimedes-|
00000030  2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  |----------------|
00000040  00 28 6b ee 0b 41 6c 61  6e 20 54 75 72 69 6e 67  |.(k..Alan Turing|
00000050  2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  |----------------|
00000060

注:每行显示16字节,两行(32字节)对应一条完整记录。


核心实现思路

  1. 校验文件有效性:先获取文件总字节数,若无法被32整除,说明文件损坏,直接判定目标名称不存在
  2. 逐记录匹配:
    • 每次从文件读取32字节到record结构体
    • 先对比目标名称长度与当前记录的name_len,长度不一致直接跳过
    • 长度一致时,用memcmp安全对比目标名称与记录name字段的前name_len个字节
    • 找到匹配记录立即返回存在;遍历完所有记录未匹配则返回不存在

C语言示例代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "records.h"

// 检查文件中是否存在指定名称,存在返回1,不存在返回0
int has_name(const char *filename, const char *target_name) {
    FILE *fp = fopen(filename, "rb");
    if (!fp) {
        perror("Failed to open file");
        return 0;
    }

    // 获取文件大小
    fseek(fp, 0, SEEK_END);
    long file_size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    // 校验文件大小是否符合记录格式
    if (file_size % sizeof(record) != 0) {
        fclose(fp);
        return 0;
    }

    size_t record_count = file_size / sizeof(record);
    record rec;
    size_t target_len = strlen(target_name);

    for (size_t i = 0; i < record_count; i++) {
        if (fread(&rec, sizeof(record), 1, fp) != 1) {
            break;
        }

        // 长度不匹配直接跳过
        if (rec.name_len != target_len) {
            continue;
        }

        // 内存对比,避免无终止符字符串的安全问题
        if (memcmp(target_name, rec.name, target_len) == 0) {
            fclose(fp);
            return 1;
        }
    }

    fclose(fp);
    return 0;
}

// 测试入口
int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <dat_file> <target_name>\n", argv[0]);
        return 1;
    }

    int result = has_name(argv[1], argv[2]);
    printf("Name '%s' %s in the file.\n", argv[2], result ? "exists" : "does NOT exist");
    return 0;
}

关键注意事项

  • 禁止使用strcmp:记录的name字段无终止符,直接用strcmp会读取内存中多余数据,引发未定义行为,必须用memcmp结合name_len
  • 二进制模式打开:Windows系统下必须用"rb"模式打开,避免换行符转换破坏二进制记录结构
  • 异常处理:需处理文件打开失败、读取中断、文件格式损坏等场景,避免程序崩溃
  • 字节序无关:本次匹配逻辑不涉及suncents字段,无需处理x86-64的小端序问题;若后续处理金额字段则需注意

内容的提问来源于stack exchange,提问作者Catherine LU

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 00:45:23