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

C语言如何读取文本文件并提取冒号后的指定内容?

解决提取配置文件冒号后内容的问题

你的现有代码存在几个关键问题:

  • 用feof作为循环条件容易导致最后一行重复读取或漏读
  • 找到冒号后直接把冒号字符赋值给r.startCash,完全没获取到冒号后面的实际内容
  • 没有区分不同配置项的类型(数字/Yes/No),也没有对应到Rules结构体的各个字段

下面是两种可靠的解决思路:


思路1:利用固定格式直接匹配读取

因为你的配置文件每行格式是固定的Key: Value,可以直接用fscanf的格式字符串精准匹配每个配置项,这种方式简单高效:

首先先正确定义Rules结构体:

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

// 定义规则结构体,对应配置文件的每个项
typedef struct {
    int startCash;
    int turnLimit;
    int playersLeftToEnd;
    int propertySetMultiplier;
    int housesBeforeHotels;
    int mustBuildEvenly;       // 1=Yes, 0=No
    int putMoneyInFreeParking; // 1=Yes, 0=No
    int auctionProperties;     // 1=Yes, 0=No
    int salaryMultiplierOnGo;
} Rules;

然后实现读取函数:

void readRules(char* file_name) {
    Rules r;
    FILE *file = fopen(file_name, "r");
    if (file == NULL) {
        printf("Could not open %s\n", file_name);
        return;
    }

    // 按固定格式读取每个配置项,跳过冒号前的文本,直接读取冒号后的值
    fscanf(file, "Starting Cash: %d", &r.startCash);
    fscanf(file, "Turn Limit (-1 for no turn limit): %d", &r.turnLimit);
    fscanf(file, "Number of Players Left To End Game: %d", &r.playersLeftToEnd);
    fscanf(file, "Property Set Multiplier: %d", &r.propertySetMultiplier);
    fscanf(file, "Number of Houses Before Hotels: %d", &r.housesBeforeHotels);
    
    // 处理Yes/No类型的项,先读字符串再转成整数标记
    char yesNo[4];
    fscanf(file, "Must Build Houses Evenly: %3s", yesNo);
    r.mustBuildEvenly = strcmp(yesNo, "Yes") == 0 ? 1 : 0;
    
    fscanf(file, "Put Money In Free Parking: %3s", yesNo);
    r.putMoneyInFreeParking = strcmp(yesNo, "Yes") == 0 ? 1 : 0;
    
    fscanf(file, "Auction Properties: %3s", yesNo);
    r.auctionProperties = strcmp(yesNo, "Yes") == 0 ? 1 : 0;
    
    fscanf(file, "Salary Multiplier For Landing On Go: %d", &r.salaryMultiplierOnGo);

    // 测试输出读取到的内容
    printf("Starting Cash: %d\n", r.startCash);
    printf("Turn Limit: %d\n", r.turnLimit);
    printf("Must Build Evenly: %s\n", r.mustBuildEvenly ? "Yes" : "No");
    // 其他字段可以类似输出

    fclose(file);
}

思路2:逐行读取并分割键值对(更通用)

如果以后配置项可能变化,或者想做更通用的解析,可以逐行读取,然后找到冒号的位置,提取后面的内容:

void readRules(char* file_name) {
    Rules r;
    FILE *file = fopen(file_name, "r");
    if (file == NULL) {
        printf("Could not open %s\n", file_name);
        return;
    }

    char line[256];
    // 逐行读取,直到文件结束
    while (fgets(line, sizeof(line), file) != NULL) {
        // 找到冒号的位置
        char* colonPos = strchr(line, ':');
        if (colonPos == NULL) {
            continue; // 跳过无效行
        }
        // 冒号后移一位,跳过空格,得到值的起始位置
        char* valueStart = colonPos + 1;
        while (*valueStart == ' ') {
            valueStart++;
        }

        // 根据行首的关键字匹配对应的字段
        if (strstr(line, "Starting Cash") != NULL) {
            sscanf(valueStart, "%d", &r.startCash);
        } else if (strstr(line, "Turn Limit") != NULL) {
            sscanf(valueStart, "%d", &r.turnLimit);
        } else if (strstr(line, "Must Build Houses Evenly") != NULL) {
            char yesNo[4];
            sscanf(valueStart, "%3s", yesNo);
            r.mustBuildEvenly = strcmp(yesNo, "Yes") == 0 ? 1 : 0;
        }
        // 其他字段类似添加判断
    }

    // 输出测试
    printf("Starting Cash: %d\n", r.startCash);
    printf("Must Build Evenly: %s\n", r.mustBuildEvenly ? "Yes" : "No");

    fclose(file);
}

关键注意点:

  • 不要用feof作为循环条件,应该用fgets或fscanf的返回值来判断是否读取成功
  • 处理Yes/No时,用strcmp比较字符串,转成整数存储更方便后续逻辑判断
  • 读取字符串时要注意缓冲区大小,避免溢出(比如用%3s读取Yes/No,因为最多3个字符)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:01:10