【问题标题】:c++ Mixing printf with wprintf (or cout with wcout)c++ 将 printf 与 wprintf 混合(或 cout 与 wcout)
【发布时间】:2011-02-12 02:27:46
【问题描述】:

我知道您不应该将打印与 printf,cout 和 wprintf,wcout 混合使用,但是很难找到一个好的答案,为什么以及是否可以绕过它。问题是我使用了一个使用 printf 打印的外部库,而我自己使用的是 wcout。如果我做一个简单的例子,它可以正常工作,但是从我的完整应用程序中它根本不会打印 printf 语句。如果这真的是一个限制,那么会有很多库无法与广泛的打印应用程序一起使用。对此的任何见解都非常受欢迎。

更新:

我把它归结为:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

#include <readline/readline.h>
#include <readline/history.h>

int main()
{
    char *buf;

    std::wcout << std::endl; /* ADDING THIS LINE MAKES PRINTF VANISH!!! */

    rl_bind_key('\t',rl_abort);//disable auto-complete

    while((buf = readline("my-command : "))!=NULL)
    {
        if (strcmp(buf,"quit")==0)
            break;

        std::wcout<<buf<< std::endl;

        if (buf[0]!=0)
            add_history(buf);
    }

    free(buf);

    return 0;
}

所以我猜这可能是冲洗问题,但对我来说仍然很奇怪,我必须检查一下。

更新 -> 解决方法:

首先,同样的问题出现在 wprintf 中。但我发现添加:

std::ios::sync_with_stdio(false);

实际上做到了...(注意错误,而不是我期望的正确..),唯一困扰我的是我不明白为什么以及如何弄清楚:-(

【问题讨论】:

  • 我把它归结为以下内容:#include #include #include #include #include int main() { 字符 buf;标准::wcout 添加此行会使打印消失!!! */ rl_bind_key('\t',rl_abort);//禁用自动完成 while((buf = readline("my-command : "))!=NULL) { if (strcmp(buf,"quit")== 0) 中断; std::wcout
  • 抱歉我的错误显然不能与代码 sn-ps 一起使用。
  • 为什么答案集中在混合coutprintf,而问题是混合coutwcout...
  • 不,不是,因为在readline函数里面,有printf语句。
  • @Kenny:因为标题没有说清楚。我会努力改进的。

标签: c++


【解决方案1】:

您应该可以混合使用它们,但它们通常使用单独的缓冲机制,因此它们会相互重叠:

printf("hello world");
cout << "this is a suprise";

可能导致:

你好,这是一个惊喜的世界

您没有提供足够的信息来诊断您的应用程序中的 printf() 问题,但我怀疑您有多个 c 运行时(一个在您的代码中,一个在 printf() 代码中)并且有一个冲突。

【讨论】:

  • 我所做的是使用 GNU readline 库来获取命令行历史。所以我的应用程序与这个库链接。
  • 我可以补充一点,如果我们谈论混合 cout 和 wcout(而不是 printf 和 wcout),那么根据我的经验,这不仅仅是一个问题,应用程序可能会崩溃。感谢您的回答。
  • @Bo Jensen:这不是 wcout 的错。那是你的错。要么就是这样,要么你的 C++ 标准库实现中存在错误。
  • 不过,这应该不太可能。默认情况下,cout 和 C 的输出流应该是同步的 (cplusplus.com/reference/iostream/ios_base/sync_with_stdio)。在循环中输出大约 100 次,看看它输出了什么。然后关闭同步并重试。
【解决方案2】:

我认为你在谈论 std::ios_base::sync_with_stdio,但 IIRC 默认情况下它是打开的。

【讨论】:

    【解决方案3】:

    printf() 和 cout 缓冲区默认情况下是同步的,或者实际上是同一个缓冲区。如果您遇到缓冲问题,显而易见的解决方案是在每次输出后刷新缓冲区:

    fflush( stdout );
    cout.flush();
    

    这会将缓冲区刷新到操作系统,一旦完成,就不可能出现交错或输出丢失。

    【讨论】:

      【解决方案4】:

      缓解头痛。不过,您通常可以,因为它们是同步的。告诉您不要这样做的人可能是那些记得使用多种 io 方法并希望将您从中拯救出来的痛苦的人。 (只是不要与系统调用混用。那会很痛苦。)

      【讨论】:

        【解决方案5】:

        库不应对标准句柄使用 printf、cout 或任何其他 I/O。他们应该使用回调例程将输出委托给主程序选择的方法。

        一个明显的例外是一个库,其唯一目的是输出,但是主程序选择使用它。而且这个规则并没有禁止对库打开的文件描述符进行 I/O。

        这不仅可以解决这里提出的问题,而且还可以处理断开连接的操作(没有 tty 的 linux 程序,例如通过 nohup 或 Win32 服务运行)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-02-15
          • 2013-09-11
          • 2016-08-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-17
          相关资源
          最近更新 更多