从C ++中的stdin读取长度大于4096字节的字符串

时间:2014-04-05 20:07:48

标签: c++

我试图以10 ^ 5的顺序读取一串长度。如果字符串的大小超过4096,我会得到不正确的字符串。 我使用以下代码

string a;
cin>>a;

这没有用,然后我尝试通过跟随代码

逐个字符地阅读
unsigned char c;
vector<unsigned char> a;
while(count>0){
 c = getchar();
 a.push_back(c);
 count--;
}

我已经完成了使用getchar的必要转义,这也有4096字节的问题。有人可以建议解决方法或指出正确的阅读方式。

3 个答案:

答案 0 :(得分:2)

这比C ++问题更可能是平台/操作系统问题。您正在使用什么操作系统,以及您使用什么方法将字符串输入到标准输入?命令行参数的上限通常是一定的。

特别是,考虑到你曾经尝试过一次阅读一个角色,但它仍然无法正常工作,这似乎是将字符串带到程序的问题,而不是C ++问题。

答案 1 :(得分:2)

根据您发布的内容使用此测试程序:

#include <iostream>
#include <string>


int main()
{
    std::string a;

    std::cin >> a;

    std::cout << a.length() << std::endl;
}

我能做到:

./a.out < fact100000.txt

并获得输出:

456574

但是,如果我从编辑器复制粘贴到控制台,则会在4095处停止。我希望在控制台副本的某处可以限制粘贴处理#g 。对此的简单解决方案当然是不使用copy&#39; n&#39;粘贴,而是从文件重定向。在一些其他系统上,对4KB输入的重构当然可以驻留在其他地方。 (注意,至少在我的系统上,我可以愉快地将450KB的析因结果复制并粘贴到另一个编辑器窗口,所以在我的系统中它只是控制台缓冲区的问题)。

答案 2 :(得分:0)

这是因为您的终端输入缓存在内核的I/O queue中。

  

终端设备的输入和输出队列在内核中实现一种缓冲形式,与I / O流实现的缓冲无关。

     

终端输入队列有时也称为其先行缓冲区。它包含从终端接收但尚未被任何进程读取的字符。

     

输入队列的大小由MAX_INPUT和_POSIX_MAX_INPUT参数描述;

默认情况下,您的终端位于Canonical mode

  

在规范模式下,所有输入都会保留在队列中,直到收到换行符,因此当您输入很长的行时,终端输入队列可能会填满。

我们可以将终端的输入模式从canonical mode更改为non-canonical mode.

您可以从终端进行:

$ stty -icanon (change the input mode to non-canonical)
$ ./a.out (run your program)
$ stty icanon (change it back to canonical)

或者您也可以以编程方式进行,

要以编程方式更改输入模式,我们必须使用low level terminal interface

所以你可以这样做:

#include <iostream>
#include <string>
#include <stdio.h>
#include <termios.h> 
#include <unistd.h>

int clear_icanon(void)
{
  struct termios settings;
  int result;
  result = tcgetattr (STDIN_FILENO, &settings);
  if (result < 0)
    {
      perror ("error in tcgetattr");
      return 0;
    }

  settings.c_lflag &= ~ICANON;

  result = tcsetattr (STDIN_FILENO, TCSANOW, &settings);
  if (result < 0)
    {
      perror ("error in tcsetattr");
      return 0;
   }
  return 1;
}


int main()
{
    clear_icanon(); // Changes terminal from canonical mode to non canonical mode.

    std::string a;

    std::cin >> a;

    std::cout << a.length() << std::endl;
}