You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C语言读取main.txt:空格数不固定时如何逐行获取每个值?

解决多行多空格分隔文本的逐行取值问题

嘿,这个场景我太熟悉了!fscanf()默认虽然会跳过空格,但如果是要逐行处理同时应对不固定数量的空格分隔,确实容易卡壳。下面给你两个实用的C语言方案,完全能替代原有fscanf()的取值逻辑:

方法一:fgets() + strtok()(最常用)

先逐行读取整行内容,再用strtok()按空格(支持连续空格)拆分每个值,这是处理这类问题的标准操作:

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

int main() {
    FILE *file = fopen("main.txt", "r");
    if (!file) {
        perror("Failed to open main.txt");
        return 1;
    }

    char line[256]; // 根据你的文本行长度调整缓冲区大小
    while (fgets(line, sizeof(line), file)) {
        // 先去掉行尾的换行符(避免影响后续拆分)
        line[strcspn(line, "\n")] = '\0';

        // 用空格、制表符作为分隔符,拆分第一个值
        char *token = strtok(line, " \t");
        while (token != NULL) {
            // 这里替换成你处理每个值的逻辑,比如转存到变量、计算等
            printf("读取到值:%s\n", token);
            // 继续拆分下一个值
            token = strtok(NULL, " \t");
        }
    }

    fclose(file);
    return 0;
}

关键说明:

  • strtok()会自动跳过连续的分隔符(不管多少空格),完美适配你的场景;
  • strcspn()用来快速定位换行符并替换为结束符,避免换行符被当成值的一部分;
  • 如果你的分隔符还有其他类型(比如逗号),可以直接加到strtok()的分隔符参数里,比如" \t,"

方法二:fgets() + sscanf()配合%n(更灵活的格式化读取)

如果你还是想用类似scanf的格式化方式,可以用sscanf()%n参数记录已读取的字符位置,循环处理整行:

#include <stdio.h>

int main() {
    FILE *file = fopen("main.txt", "r");
    if (!file) {
        perror("Failed to open main.txt");
        return 1;
    }

    char line[256];
    while (fgets(line, sizeof(line), file)) {
        char value[64];
        int read_len = 0;
        // 从当前位置开始读取,%s自动跳过前导空格,%n记录已读字符数
        while (sscanf(line + read_len, "%s%n", value, &read_len) == 1) {
            printf("读取到值:%s\n", value);
            // 这里可以根据需要换成int/float类型,比如"%d%n"
        }
    }

    fclose(file);
    return 0;
}

关键说明:

  • %s本身就会忽略前导的空白字符(空格、换行、制表符),所以不管多少空格都能正确取值;
  • %n会把本次sscanf读取的字符数存入read_len,下次循环就从新的位置开始读取,不会重复处理;
  • 如果需要读取数值类型(比如int、float),直接把%s换成%d%f即可,非常灵活。

额外注意事项:

  • 确保linevalue的缓冲区大小足够容纳你的最长行和最长值,避免缓冲区溢出;
  • 如果你的文本中存在带空格的取值(比如"hello world"作为一个整体值),那上面两种方法都不适用,需要用引号分隔等规则处理,这种情况可以再提出来细化方案~

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

火山引擎 最新活动