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

C语言中如何让fscanf读取数字的循环在到达行尾时停止?

问题根源

你原来的逻辑跑不通核心是两个层面的问题:

  • fscanf使用%i格式读取整数时,会自动跳过所有前导空白字符,包括空格、换行符、制表符,换行符根本不会被当成整数内容读入,所以你写的new->data != '\n'终止条件永远触发不了,会直接跨到下一行继续读。
  • 你贴的原代码本身还有几个会直接崩溃的bug:
    • 遍历找链表尾节点的循环会把temp指针走到NULL,后续访问temp->next会直接触发段错误
    • new变量定义在do循环的内部块中,while判断条件的作用域访问不到这个变量
    • 没有检查fscanf、malloc的返回值,一旦文件读结束或者内存分配失败会直接出现野指针。
推荐实现方式

最稳妥、逻辑最清晰的方案是先把整行内容一次性读入内存缓冲区,再在缓冲区内部解析当前行的所有数字,天然实现行级隔离,读完一行的所有数字就自动退出内层循环,外层循环直接处理下一行即可,完全不需要手动在文件流里判断换行位置。
具体实现代码参考:

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

#define LINE_BUF_MAX 102400 // 根据单行最大数字长度调整,足够存下一行所有内容即可

// 链表节点结构定义
typedef struct node {
    int data;
    struct node *next;
    struct node *prev;
} node;

// 链表尾插辅助函数,避免每次插节点都从头遍历,提升大数量场景下的效率
void append_node(node **head, node **tail, int data) {
    node *new_node = (node*)malloc(sizeof(node));
    new_node->data = data;
    new_node->next = NULL;
    new_node->prev = *tail;
    if (*head == NULL) {
        *head = new_node;
        *tail = new_node;
        return;
    }
    (*tail)->next = new_node;
    *tail = new_node;
}

int main() {
    FILE *fp = fopen("你的数字文件路径", "r");
    if (!fp) {
        perror("文件打开失败");
        return 1;
    }
    const int N = 100; // 按你实际需要读取的总行数修改
    node *list_arr[N]; // 链表数组,每个索引对应一行的链表头节点
    char line_buf[LINE_BUF_MAX];

    for (int i = 0; i < N; i++) {
        node *head = NULL;
        node *tail = NULL;
        // 先把整行内容读入缓冲区
        if (fgets(line_buf, LINE_BUF_MAX, fp) == NULL) break; // 文件提前读完直接退出
        char *pos = line_buf;
        int num, offset;
        // 从缓冲区里逐个读取空格分隔的数字,直到行尾
        while (sscanf(pos, "%i%n", &num, &offset) == 1) {
            append_node(&head, &tail, num);
            pos += offset; // 移动读取指针,跳过已经读完的内容
        }
        list_arr[i] = head; // 当前行链表存入数组对应索引
    }

    fclose(fp);
    // 后续你的业务处理逻辑
    return 0;
}

代码里用到的%n是sscanf的格式控制符,作用是返回本次格式匹配从缓冲区起始位置一共读取了多少个字符,靠这个值移动读取指针,就能依次把一行里所有空格分隔的数字读出来,整行读完后内层循环自然终止,不会跨行读取下一行的内容。
如果你非要直接在文件流上不读整行实现,需要每次读取整数前先逐个预读字符判断是不是换行,遇到换行就把字符回退到流里再退出内层循环,但这种实现需要处理很多边界情况(比如行尾多余空格、空行),出错概率远高于先读整行的方案,不推荐使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 23:48:26