针对你在期末考试或 LeetCode 刷题中遇到的“未知长度多组数据录入”的情况,C++ 有几种标准的处理模式。

C++ 处理未知长度/多组数据录入的常用模板

在数据结构考试或算法题(OJ/LeetCode)中,通常没有明确告诉你“一共有多少个数字”,而是说“直到输入结束”或“输入为0时停止”。以下是标准解决方案:

1. 利用 cin 的返回值 (C++ 标准写法)

cin >> x 表达式在 C++ 中会返回输入流对象本身。在 while 循环条件中,它会被隐式转换为 bool 类型。

  • 如果读取成功,返回 true
  • 如果遇到 EOF (End Of File) 或格式错误,返回 false

场景 A:每次读取一个数

1
2
3
4
5
6
7
8
9
10
11
12
int x;
// 当输入流没有结束时,循环继续
while (cin >> x) {
// 处理 x,例如插入链表
process(x);
}
````

### 场景 B:每次读取两个数 (常见于图论边的输入)

C++

int a, b;
// 只有当 a 和 b 都成功读取时,才进入循环
while (cin >> a >> b) {
// 处理边 (a, b)
addEdge(a, b);
}

1
2
3
4
5
6
7
8
9

## 2. 利用 `scanf` 的返回值 (C 语言风格 / 高性能)

在输入数据量极大(超过 $10^5$ 级别)时,scanf 比 cin 快。

scanf 返回成功读取的变量个数。如果遇到文件结束符,它会返回宏 EOF (通常是 -1)。

C++


int x;
// 只要返回值不等于 EOF,就说明还有数据
while (scanf("%d", &x) != EOF) {
// 处理 x
process(x);
}
1
2
3
4
5
6
7

## 3. 特定停止条件 (Sentinel Value)

有时候题目会规定:“输入 0 结束”或“输入 -1 结束”。

C++


int x;
while (cin >> x && x != 0) {
// 注意:这里的逻辑是,读取了 x,且 x 不为 0 时才进入
// 如果输入 0,循环直接终止
process(x);
}
1
2
3
4
5
6
7

## 4. 整行读取 (针对字符串)

如果你需要读入一行带空格的字符串,直到文件结束。

C++


string line;
while (getline(cin, line)) {
// line 中包含了整行内容(不含换行符)
process(line);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

---

## ⚠️ 重要提示:在本地 IDE 如何结束输入?

在 LeetCode 或学校 OJ 上,系统会自动发送 EOF 信号。但在你本地的 VSCode 或 CLion 的控制台里,程序会一直等待输入。你需要手动输入 **EOF**:

- **Windows:** 输入完数据后,按 `Ctrl + Z`,然后回车。

- **Mac / Linux:** 输入完数据后,按 `Ctrl + D`。


---

## 🔥 实战应用:未知长度数据构建链表

结合你正在复习的链表,这是考试中建立链表的标准模板(使用**尾插法**,保证链表顺序与输入顺序一致):

C++

include

struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};

int main() {
// 1. 创建虚拟头节点 (Dummy Head),简化操作
ListNode dummyHead = new ListNode(0);
ListNode
tail = dummyHead; // tail 永远指向链表最后一个节点

int val;
std::cout << "请输入一组整数 (Windows按Ctrl+Z结束, Mac按Ctrl+D结束):" << std::endl;

// 2. 核心循环:读取直到 EOF
while (std::cin >> val) {
    ListNode* newNode = new ListNode(val);
    tail->next = newNode; // 链接
    tail = newNode;       // 更新尾指针
}

// 3. 此时链表构建完成,头节点是 dummyHead->next
ListNode* realHead = dummyHead->next;

// (可选) 遍历打印验证
ListNode* p = realHead;
while (p != nullptr) {
    std::cout << p->val << " -> ";
    p = p->next;
}
std::cout << "NULL" << std::endl;

return 0;

}
```