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

如何在C语言中实现文本文件特定内容的搜索与存储算法

C语言文本文件搜索与数据提取实现方案

需求明确

  • 核心功能:遍历文本文件,根据**测量模块(如A11)和测量量类型(如R1)**定位目标条目
  • 需提取存储的数据:
    • 测量模块所在行的上一行内容(如设备ID 9403133410)
    • 测量量类型行后的连续3行数据(数值、时间、日期)
  • 命令逻辑约束:
    • 未执行v命令打开文件时,任何搜索操作输出Not opened file
    • 搜索结果默认按日期时间排序,无需额外激活n命令

文本文件示例片段

9403133410
A11
R1
25.6
14:35:22
2024-05-20
B07
T2
30.1
15:01:10
2024-05-20
A11
R1
24.8
16:20:05
2024-05-19

输入输出要求

  • 输入:search <模块ID> <测量类型>(如search A11 R1)
  • 输出:
    • 文件未打开时:Not opened file
    • 无匹配条目时:No matching entries found
    • 匹配成功时:按日期时间升序排列的提取数据,格式示例:
      Found 2 matching entries (sorted by datetime):
      
      Entry 1:
      Device ID: 9403133410
      Module: A11
      Measurement Type: R1
      Value: 24.8
      Time: 16:20:05
      Date: 2024-05-19
      
      Entry 2:
      Device ID: 9403133410
      Module: A11
      Measurement Type: R1
      Value: 25.6
      Time: 14:35:22
      Date: 2024-05-20
      

完整代码实现

基础代码(原文件读取逻辑)

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

#define MAX_LINE 256
FILE *fp = NULL;

void cmd_v(const char *filename) {
    if (fp != NULL) fclose(fp);
    fp = fopen(filename, "r");
    if (!fp) {
        printf("Failed to open file\n");
    }
}

int main() {
    char cmd[MAX_LINE];
    while (1) {
        printf("> ");
        fgets(cmd, MAX_LINE, stdin);
        cmd[strcspn(cmd, "\n")] = '\0';
        
        if (strncmp(cmd, "v ", 2) == 0) {
            cmd_v(cmd + 2);
        } else if (strcmp(cmd, "q") == 0) {
            if (fp) fclose(fp);
            exit(0);
        }
    }
    return 0;
}

完善后的功能代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAX_LINE 256
#define MAX_ENTRIES 100

// 存储提取数据的结构体
typedef struct {
    char device_id[MAX_LINE];
    char module[MAX_LINE];
    char type[MAX_LINE];
    char value[MAX_LINE];
    char time[MAX_LINE];
    char date[MAX_LINE];
    time_t timestamp; // 用于排序的时间戳
} MeasurementData;

FILE *fp = NULL;
MeasurementData entries[MAX_ENTRIES];
int entry_count = 0;

// 将日期时间转换为时间戳
time_t get_timestamp(const char *date, const char *time_str) {
    struct tm tm = {0};
    sscanf(date, "%d-%d-%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday);
    sscanf(time_str, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
    tm.tm_year -= 1900;
    tm.tm_mon -= 1;
    return mktime(&tm);
}

// 按时间戳升序排序
void sort_entries() {
    for (int i = 0; i < entry_count - 1; i++) {
        for (int j = i + 1; j < entry_count; j++) {
            if (entries[i].timestamp > entries[j].timestamp) {
                MeasurementData temp = entries[i];
                entries[i] = entries[j];
                entries[j] = temp;
            }
        }
    }
}

// 搜索并提取数据
void search_data(const char *target_module, const char *target_type) {
    if (!fp) {
        printf("Not opened file\n");
        return;
    }

    entry_count = 0;
    char line[MAX_LINE];
    char prev_line[MAX_LINE] = {0};
    int state = 0; // 0:初始态 1:找到目标模块 2:找到目标类型 3-5:读取后续3行

    fseek(fp, 0, SEEK_SET);
    while (fgets(line, MAX_LINE, fp) != NULL && entry_count < MAX_ENTRIES) {
        line[strcspn(line, "\n\r")] = '\0';
        if (strlen(line) == 0) continue;

        switch (state) {
            case 0:
                strncpy(prev_line, line, MAX_LINE - 1);
                if (strcmp(line, target_module) == 0) state = 1;
                break;
            case 1:
                if (strcmp(line, target_type) == 0) {
                    strncpy(entries[entry_count].device_id, prev_line, MAX_LINE - 1);
                    strncpy(entries[entry_count].module, target_module, MAX_LINE - 1);
                    strncpy(entries[entry_count].type, target_type, MAX_LINE - 1);
                    state = 2;
                } else {
                    strncpy(prev_line, line, MAX_LINE - 1);
                    state = 0;
                }
                break;
            case 2:
                strncpy(entries[entry_count].value, line, MAX_LINE - 1);
                state = 3;
                break;
            case 3:
                strncpy(entries[entry_count].time, line, MAX_LINE - 1);
                state = 4;
                break;
            case 4:
                strncpy(entries[entry_count].date, line, MAX_LINE - 1);
                entries[entry_count].timestamp = get_timestamp(entries[entry_count].date, entries[entry_count].time);
                entry_count++;
                strncpy(prev_line, line, MAX_LINE - 1);
                state = 0;
                break;
        }
    }

    sort_entries();

    if (entry_count == 0) {
        printf("No matching entries found\n");
        return;
    }
    printf("Found %d matching entries (sorted by datetime):\n", entry_count);
    for (int i = 0; i < entry_count; i++) {
        printf("\nEntry %d:\n", i + 1);
        printf("Device ID: %s\n", entries[i].device_id);
        printf("Module: %s\n", entries[i].module);
        printf("Measurement Type: %s\n", entries[i].type);
        printf("Value: %s\n", entries[i].value);
        printf("Time: %s\n", entries[i].time);
        printf("Date: %s\n", entries[i].date);
    }
}

void cmd_v(const char *filename) {
    if (fp != NULL) fclose(fp);
    fp = fopen(filename, "r");
    if (!fp) {
        printf("Failed to open file\n");
    } else {
        printf("File opened successfully\n");
    }
}

int main() {
    char cmd[MAX_LINE];
    while (1) {
        printf("> ");
        fgets(cmd, MAX_LINE, stdin);
        cmd[strcspn(cmd, "\n")] = '\0';

        if (strncmp(cmd, "v ", 2) == 0) {
            cmd_v(cmd + 2);
        } else if (strncmp(cmd, "search ", 7) == 0) {
            char *module = strtok(cmd + 7, " ");
            char *type = strtok(NULL, " ");
            if (module && type) {
                search_data(module, type);
            } else {
                printf("Invalid format: use 'search <module> <type>'\n");
            }
        } else if (strcmp(cmd, "q") == 0) {
            if (fp) fclose(fp);
            exit(0);
        } else {
            printf("Unknown command. Available: v <filename>, search <module> <type>, q\n");
        }
    }
    return 0;
}

关键实现说明

  • 状态机遍历:通过状态变量跟踪文件读取进度,确保精准匹配模块、类型并提取后续数据
  • 时间戳排序:将日期时间转换为time_t类型,实现默认按时间升序排序
  • 命令扩展:新增search命令,支持直接输入模块和类型进行搜索
  • 边界处理:包含文件未打开提示、条目数量上限、无效命令提示等异常处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 01:41:30