提问人:Richard Wang 提问时间:12/31/2022 更新时间:12/31/2022 访问量:141
解析大型整数输入时 C++ 输入/输出中的奇怪行为
Strange Behavior in C++ Input/Output When Parsing Large Integer Input
问:
我有以下一段代码:
#include <iostream>
using namespace std;
int main() {
// Number of inputs
int N;
scanf("%d", &N);
// Takes in input and simply outputs the step it's on
for (int i = 0; i < N; i++) {
int Temp;
scanf("%d", &Temp);
printf("%d ", i);
}
}
当接收大量整数输入时,C++ 会停在打印输出的某个点,似乎在等待更多输入的到来。 给定输入 2049 个 1,程序在打印 2048 个整数(0 到 2047)后停止,并且不打印最终的 2048(第 2049 个整数)。2048 看起来很可疑,是 2 的幂。 似乎情况是,输入值越大,程序决定停止的速度就越快,在这种情况下,在看起来像是随机步骤之后。例如,我给了它 991 个整数(最多一万个),程序在迭代 724 后停止输出。 请注意,我将数字复制并粘贴为一个整体块,而不是一个接一个地输入和输入它们,但我怀疑这起了作用。我也尝试过 cin 和 cout,但它们没有帮助。 有人可以解释一下这种现象背后的原因吗?
答:
我的第一个想法是,你在输入端遇到了某种障碍......
命令行长度的限制[通常]不是由 shell 强加的,而是由操作系统强加的。
然而,情况可能并非如此。
首先,专注于您的数据,确保您的数据是您认为的(没有意外字符),然后尝试调试您的读取,确保这些值像您预期的那样进入内存。
尝试将读取和写入分成两个循环,这可能会根据您的技能水平帮助您更轻松地进行调试,但同样,请确保您的读取不会发生一些时髦的事情。对这个的阅读高度怀疑......
下面有几个裂缝......还没测试过。希望这有帮助!
#include <iostream>
int main() {
int N;
std::cin >> N;
// Read N integers, storing to array
int* numbers = new int[N];
for (int i = 0; i < N; i++) {
std::cin >> numbers[i];
}
// Print
for (int i = 0; i < N; i++) {
std::cout << numbers[i] << " ";
}
std::cout << std::endl;
// Free the dynamically allocated memory
delete[] numbers;
return 0;
}
好。。。也许更优化一点......
#include <iostream>
int main() {
int N;
std::cin >> N;
// fixed-size on the stack
int numbers[N];
// cin.tie(nullptr) and ios::sync_with_stdio(false) might improve perf.
std::cin.tie(nullptr);
std::ios::sync_with_stdio(false);
// Read N integers, storing to array
for (int i = 0; i < N; i++) {
std::cin >> numbers[i];
}
// Print
for (int i = 0; i < N; i++) {
std::cout << numbers[i] << " ";
}
std::cout << std::endl;
return 0;
}
评论
new
delete
std::vector
std::make_unique<int[]>
int numbers[N];
N
我已经找到了问题的答案。失败背后的原因确实是由于复制和粘贴了大量输入,正如许多人所建议的那样,我感谢大家的帮助。但是,没有不正确的字符,导致此问题的原因是规范模式造成的 4096 个字符限制。
在规范模式下,终端允许用户使用箭头键、退格键等导航输入。仅当存在换行符或缓冲区已满时,它才会将文本发送到处理器。这个缓冲区的大小是 4096 个字符,很明显为什么代码无法解析比这更多的输入,即 2049 s 是 4098 个字符。可以切换到非规范模式,该模式允许更大的输入,但代价是无法导航它,使用 .输入后,它又回到了规范模式。"1 "
stty -icanon
stty icanon
实际上,用换行符分隔数字输入输入似乎是最简单的解决方法。
这个来源对我很有帮助:http://blog.chaitanya.im/4096-limit。 这篇关于 unix 堆栈交换的帖子与我的问题类似:https://unix.stackexchange.com/questions/131105/how-to-read-over-4k-input-without-new-lines-on-a-terminal。
上一个:是否可以在 c++ 中同时使用空格和回车键来获取输入?
下一个:带变量的基本输出
评论
scanf
scanf
printf
scanf()
cin
scanf()
1
0
EOF