c++ - 关于 unistd.h (C++) 中的 read()

标签 c++ unistd.h

所有,我正在设计一个Key-Value服务器,当我写客户端时,我发现了一个非常奇怪的事情,看简化代码:

while(1)
{
    printf("->:");
    read(STDIN_FILENO, buf, sizeof(buf));
    write(client_sock, buf, sizeof(buf));
    int m = read(client_sock, buf, sizeof(buf));
    buf[m] = '\0';
    printf("%s", buf);
}

当我运行程序时,它首先要求输入,所以我输入了一些东西,但没有任何反应! (服务器运行良好,当我使用其他客户端时,它很好地回显了一些东西)

然后我只更改一行代码:

printf("\n->:");

然后它运行良好!为什么?为什么“\n”可以改变输出?我想可能是 read() ,但我无法解释

最佳答案

printf(3) 是 C 标准 IO 库的一部分,它执行内部缓冲以提高性能。

缓冲分为三种:无缓冲、行缓冲和 block 缓冲。

应用哪种缓冲部分取决于被写入的描述符是否为 2,以及它是否连接到终端。 (参见 isatty(3)。)

如果打印完成到 stderr (2),则不会进行缓冲。

如果对任何其他描述符进行打印,则无论它是否是终端,行为都会发生变化:如果输出是终端,则输出是行缓冲。如果输出不是终端(文件、管道、套接字等),则输出是 block 缓冲

当行缓冲时,它会在打印任何内容之前等待 \n。 (或者如果您在发送 \n 之前写入的内容足以溢出内部缓冲区。)

我建议的是以下内容:

printf("->:");
fflush(stdout);
read(STDIN_FILENO, buf, sizeof(buf));
/* ... */
printf("%s\n", buf);

这是一个小改动;您不会在程序启动时得到毫无意义的空行,并且提示应该立即出现。

您可以使用 setvbuf(3) 函数在启动时更改流的缓冲一次,如果您愿意,则无​​需再次刷新它。

int err = setvbuf(stdout, NULL, _IONBF, 0);
/* check err */

关于c++ - 关于 unistd.h (C++) 中的 read(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8550116/

相关文章:

c++ - 在包含多个字符串的多个对象中查找子字符串

c++ - 表达式无法识别函数c++中的指针

c++ - 调整 Eigen::Ref 大小的解决方法

c++ - 具有大量嵌套组合的 setter 和 getter

c++ - 如何处理 Qt5 关闭事件以终止?

c++ - 在 Linux 中打开文件。我不想创建写保护文件

c - 如何选择其中一个选项?

c - 警告 : implicit declaration of function 'daemon'

C 的 getopt 无法解析 argv 末尾(或中间)的选项