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

C语言文件操作:如何提取每行数字并进行比较?

提取每行末尾的浮点数并完成统计计算

你不需要用strtok,用fgets配合sscanf就能满足需求——因为你的文件每行最后一个元素是浮点数,前面的名称即使包含空格也不影响。下面是完整的示例代码,包含读取文件、提取分数、计算最大值、最小值、平均值的逻辑:

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

int main() {
    // 若要读取本地文件,将stdin替换为文件名,比如 "scores.txt"
    FILE *fp = stdin;
    if (!fp) {
        perror("Failed to open file");
        return 1;
    }

    char line[1000];
    float total = 0.0f;
    int valid_count = 0;
    float max_score = -INFINITY;
    float min_score = INFINITY;

    // 逐行读取直到文件末尾
    while (fgets(line, sizeof(line), fp) != NULL) {
        // 移除换行符,避免干扰后续解析
        size_t line_len = strlen(line);
        if (line_len > 0 && line[line_len - 1] == '\n') {
            line[line_len - 1] = '\0';
        }

        float score;
        // 核心逻辑:跳过所有非浮点数起始字符,读取最后一个浮点数
        // %*[^0123456789.-] 表示跳过所有不是数字、负号、小数点的内容
        if (sscanf(line, "%*[^0123456789.-]%f", &score) == 1) {
            total += score;
            valid_count++;
            if (score > max_score) max_score = score;
            if (score < min_score) min_score = score;
            printf("提取到分数:%.2f\n", score);
        } else {
            printf("该行无有效分数:%s\n", line);
        }
    }

    fclose(fp);

    // 输出统计结果
    if (valid_count > 0) {
        printf("\n=== 统计结果 ===\n");
        printf("有效行数:%d\n", valid_count);
        printf("最高分:%.2f\n", max_score);
        printf("最低分:%.2f\n", min_score);
        printf("平均分:%.2f\n", total / valid_count);
    } else {
        printf("未找到任何有效分数\n");
    }

    return 0;
}

关键细节说明

  1. 文件读取逻辑:用while (fgets(...) != NULL)替代你的do-while,这是判断文件读取完毕的标准写法,避免遗漏行或提前终止。
  2. 分数提取逻辑:
    • sscanf的扫描集%*[^0123456789.-]会跳过所有不构成浮点数开头的字符,直到遇到数字、负号或小数点,然后用%f读取浮点数。
    • 如果你的名称可能包含小数点/负号(比如名称是test-1),上面的方法会出错,这时可以改用从字符串末尾向前查找的方式:
      // 从后往前定位第一个数字相关字符
      int idx = strlen(line) - 1;
      while (idx >= 0 && !((line[idx] >= '0' && line[idx] <= '9') || line[idx] == '.' || line[idx] == '-')) {
          idx--;
      }
      if (idx >= 0) {
          char *endptr;
          float score = strtof(&line[idx], &endptr);
          // 验证转换是否成功
          if (endptr != &line[idx]) {
              // 这里处理score的统计逻辑
          }
      }
      
  3. 统计变量:直接在读取过程中计算总和、最大值、最小值,无需额外存储所有分数(如果文件很大,这种方式更节省内存)。

你的原始代码问题修正

  • lines++后面缺少分号;
  • 循环条件line[0] != '\n'错误,无法正确判断文件结束;
  • 尽量避免使用全局变量,将变量放在main函数内作为局部变量更规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:32:31