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

C语言读取TXT文件异常求助:无法正确提取姓名与时间

解决C语言读取TXT文件提取人名和时间的问题

嘿,我来帮你搞定这个文件读取的问题!你现在遇到的两个核心问题——人名带冒号、时间读错,都是因为代码里的字符读取逻辑没处理好.和:之间的空格与非空白字符,咱们一步步拆解修复:

问题出在哪?

  1. 人名带冒号:你用fscanf(f," %s %s",pnome,unome)读取人名,但%s的规则是读到空白字符就停止,而:不属于空白字符,所以当遇到Pedro Mendes:时,第二个%s会把Mendes:整个读进去,导致人名末尾带冒号。
  2. 时间读错行:在读取完错误的人名后,你用while(fgetc(f) != ':')找冒号,但此时冒号已经被前面的fscanf读进unome里了,这个循环会一直跳过字符,直到找到下一行的冒号,自然就读到下一行的时间了。

修复方案:两种可靠的实现方式

方法一:用fscanf的格式控制直接匹配

利用%[^:]格式符(表示读取所有不是冒号的字符),可以精准提取.之后、:之前的完整人名(包括空格),代码示例:

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

#define MAX_NAME 100  // 定义足够大的人名缓冲区

int main() {
    const char *filename = "seu_arquivo.txt";
    FILE *f = fopen(filename, "rt");
    if (f == NULL) {
        printf("Erro no acesso ao ficheiro.\n");
        return EXIT_FAILURE;
    }

    char fullname[MAX_NAME];
    int tempo;
    int c;

    while (!feof(f)) {
        // 跳过所有字符直到找到'.',同时避免文件结束死循环
        while ((c = fgetc(f)) != '.' && c != EOF);
        if (c == EOF) break;

        // 读取'.'之后到':'之前的所有字符(包括空格),前面的空格跳过可能的空白
        if (fscanf(f, " %99[^:]", fullname) != 1) {
            // 读取失败时跳过当前行剩余内容,避免卡死
            while ((c = fgetc(f)) != '\n' && c != EOF);
            continue;
        }

        // 跳过':'字符
        while ((c = fgetc(f)) != ':' && c != EOF);
        if (c == EOF) break;

        // 读取冒号后的时间
        if (fscanf(f, "%d", &tempo) == 1) {
            printf("Nome: %s | Tempo: %d\n", fullname, tempo);
        }

        // 跳过当前行剩余内容,准备处理下一行
        while ((c = fgetc(f)) != '\n' && c != EOF);
    }

    fclose(f);
    return EXIT_SUCCESS;
}

方法二:整行读取后解析(更灵活)

如果你的文本每条记录占一行,用fgets读取整行,再用字符串函数找.和:的位置,这种方法更直观,也不容易出错:

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

#define MAX_LINE 256

int main() {
    const char *filename = "seu_arquivo.txt";
    FILE *f = fopen(filename, "rt");
    if (f == NULL) {
        printf("Erro no acesso ao ficheiro.\n");
        return EXIT_FAILURE;
    }

    char line[MAX_LINE];
    while (fgets(line, sizeof(line), f) != NULL) {
        // 找到'.'的位置
        char *dot_pos = strchr(line, '.');
        if (dot_pos == NULL) continue;
        // 找到':'的位置(从'.'之后开始找)
        char *colon_pos = strchr(dot_pos, ':');
        if (colon_pos == NULL) continue;

        // 提取人名:从dot_pos+1到colon_pos-1
        *colon_pos = '\0';  // 把':'换成字符串结束符
        char *name = dot_pos + 1;
        // 去掉人名前后的多余空格(可选)
        while (*name == ' ') name++;
        char *name_end = colon_pos - 1;
        while (name_end > name && *name_end == ' ') name_end--;
        *(name_end + 1) = '\0';

        // 提取时间
        int tempo = atoi(colon_pos + 1);
        printf("Nome: %s | Tempo: %d\n", name, tempo);
    }

    fclose(f);
    return EXIT_SUCCESS;
}

关键注意事项

  • 缓冲区大小:定义数组时要预留足够空间,或者用%99[^:]这种带长度限制的格式符,避免缓冲区溢出。
  • 文件结束判断:所有读取操作都要检查EOF,防止死循环或读取错误内容。
  • 空白处理:如果人名前后可能有空格,记得用额外的逻辑去除(方法二里已经包含了这个处理)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 07:57:49