【问题标题】:std::string gets truncated after 4095 characters froms std::cinstd::string 在来自 std::cin 的 4095 个字符后被截断
【发布时间】:2021-08-12 23:11:46
【问题描述】:

我的程序需要从标准输入读取最多 50k 个字符的长字符串。代码如下:

#include <iostream>
#include <string>

std::string A;

int main(){
    std::cin >> A;
    std::cout << "String max: " << A.max_size() << std::endl;
    std::cout << "Size: " << A.size();

当我尝试输入一个 10k 字符长的字符串时,我得到以下输出:

String max: 4611686018427387903
Size: 4095

根据 Google 的说法,std::cinstd::string 在处理 10k 个字符时应该没有问题,但由于某种原因,A 在 4095 个字符后会被截断。我通过将字符串粘贴到默认的 Ubuntu 终端中来输入字符串。在同一个终端中将它粘贴到 Python3 中可以正常工作,这让我相信截断它的不是终端,而是 C++。我使用g++ program.cxx 编译,我有 16 GB 的 RAM。

如何从标准输入输入大字符串?任何帮助表示赞赏。

P.S.:如果您需要一个大字符串,只需将其粘贴到 Python 中:print("123"*5000)

【问题讨论】:

  • 4095 是 2 ^ 12 减 1。可疑。
  • 看起来这是你的内核强加的硬限制:stackoverflow.com/questions/18015137/…
  • 您可以通过使用管道来规避限制。在 ubuntu 上测试并使用管道我可以读取 10k 个字符,并在普通标准输入上测试并确认了 tty 限制
  • @NathanOliver 但这并不能解释 Python 如何在同一个终端上读取 10k+ 个字符串。链接问题的作者无法让它在 C 或 Python 中工作,这让我相信我们没有完全相同的问题。
  • @Jan 你如何“将它粘贴到 python3 中”? python3 -c "print(len(input()))" 遇到完全相同的问题(它使用相同的长字符串打印 4095)

标签: c++ string ubuntu stdin


【解决方案1】:

在规范模式下,您可能会遇到 Linux 终端的 4096 行限制输入。如果您尝试在 Linux 终端中输入很长的行(>4095 个字符),多余的行将被丢弃,直到您输入换行符或 eof 字符以刷新终端缓冲区。

有几种方法可以解决这个问题:

  • 在输入中每隔一段时间插入一个 eof/flush 字符(通常是 ctrl-D)——每个这样的字符都会刷新终端缓冲区,重置 4K 限制,并允许输入更长的行。注意不要在换行符或另一个 eof 之后立即插入一个,因为这会导致输入出现 EOF
  • 将终端置于非规范模式。这将导致在进程读取缓冲区时刷新缓冲区;大多数进程的读取速度通常比在终端中键入或粘贴字符的速度要快得多,因此您永远不会接近 4K 限制。

【讨论】:

    猜你喜欢
    • 2013-11-01
    • 1970-01-01
    • 2016-05-18
    • 2021-08-17
    • 2013-05-28
    • 2018-10-26
    • 2010-10-22
    • 2011-10-12
    • 2022-09-27
    相关资源
    最近更新 更多