C++ 了解系统级读写功能
由于我对std iostream和stdio不满意,我决定创建自己的io库。这对我的教育有好处 但是我有一个小问题。在终端文件描述符上操作Linux read时,在换行之前不会返回。所以如果我要求它输入10个字节,即使我输入20个字节,它也不会返回。更糟糕的是,这10个额外字节没有记录在我传递给它的缓冲区中 那10个额外的字节怎么了? Linux是否有用于读取的缓冲区?C++ 了解系统级读写功能,c++,linux,C++,Linux,由于我对std iostream和stdio不满意,我决定创建自己的io库。这对我的教育有好处 但是我有一个小问题。在终端文件描述符上操作Linux read时,在换行之前不会返回。所以如果我要求它输入10个字节,即使我输入20个字节,它也不会返回。更糟糕的是,这10个额外字节没有记录在我传递给它的缓冲区中 那10个额外的字节怎么了? Linux是否有用于读取的缓冲区? 我可以访问这个缓冲区而不是提供我自己的吗?因此,Linux终端的默认行为是行缓冲。如果你想要的话,像这样的东西可以一次读一个字
我可以访问这个缓冲区而不是提供我自己的吗?因此,Linux终端的默认行为是行缓冲。如果你想要的话,像这样的东西可以一次读一个字符 为了回答您关于获取其他10个字节的问题,如果您进行另一次读取,它将返回这些字节的其余部分。下面的示例演示了多个顺序读取。如果在提示下输入超过10个字符,则第二次读取将在不阻塞的情况下进行,并返回从10开始到19的字符。超出基于0的索引19的字符将不会被打印
#include <unistd.h>
#include <stdio.h>
int main(int argc, char** argv)
{
int read1Count = 0;
int read2Count = 0;
char pBuffer[20];
printf("Provide input: ");
// flush stdout because buffering...
fflush(NULL)
read1Count = read(1, pBuffer, 10);
// flush stdout because buffering...
fflush(NULL)
printf("Provide input: ");
read2Count = read(1, pBuffer + 10, 10);
printf("\nRead 1: '");
if (read1Count < 0)
{
perror("Error on first read");
}
for (int i = 0; i < read1Count; i++)
{
printf("%c", pBuffer[i]);
}
printf("'\nRead 2: '");
if (read2Count < 0)
{
perror("Error on second read");
}
for (int i = 0; i< read2Count; i++)
{
// We started the second read at pBuffer[10]
printf("%c", pBuffer[i + 10]);
}
printf("'\n");
}
编译并运行这个我看到了
提供输入:12345678910
提供投入:
读1:'1234567891'
阅读2:'0
“有一个ioctl可以修改此行为。Linux读取操作终端文件描述符时,在换行之前不会返回。事实并非如此。更确切地说,终端在得到一整行数据之前不会发送这些字节。例如,如果您使用PuTTY并在其选项中关闭行缓冲,您将看到。@JaveneCPPMcGowan这完全不是一回事,如果发送终端在等待换行时保留数据,那么它会对一系列修复方法产生巨大影响。幸运的是,有[特定于平台,有时不可靠]的方法可以实现这个目标,这在dupe中提到过。最终,虽然这种精细控制通常只适用于图形风格的应用程序,而现在我们有图形。它就在那里,在一个大横幅中,在问题的顶部。不一定。在未将结果存储到变量中之前,切勿读取。你必须用两种方法来测试它的错误和结束,在默认情况下,使用它作为计数。你的例子在语法上是无效的,忽略了read的返回值谢谢你冒着生命危险来帮助我。这就是为什么我恳求你编辑你的答案,以保持管理员高兴,没有必要这样做。评论部分是专门为批评性答案提供的,这样我们就可以保持事实上的准确性。这不是针对个人的。@JaveneCPPMcGowan是的,终端有一个缓冲区。不知道缓存会从哪里进入,你不知道。终端可能在世界的另一边,也可能在太空中。这就是重点。