检查C和C ++中的输出错误

时间:2015-02-07 17:08:21

标签: c++ c printf cout

我写了这个简单的程序。我知道C中的printf()函数返回成功打印的字符总数,因此以下C程序正常工作,因为任何非零值在C中都被评估为true

#include <stdio.h>

int main(void)
{
   if (printf("C"))
   return 0;
}

但是为什么以下C ++程序会编译&amp;运行得好吗?如果cout是一个对象而不是一个函数,那么为什么程序会给出预期的输出?

#include <iostream>
using namespace std;

int main() {
    if (cout << "C++")
    // your code goes here
    return 0;
}

4 个答案:

答案 0 :(得分:4)

std::cout << "C++";

是对std::operator<<(std::cout, const char*)的函数调用,它返回对std::cout的引用,该引用可转换为bool。如果true没有发生错误,它将评估为std::cout

答案 1 :(得分:1)

<<运算符返回cout。这就是为什么你可以像这样链接<<运算符:

std::cout << "Hello" << " " << "C++" << " " << "World!" << std::endl;

返回的cout将隐式转换为if中的值true

答案 2 :(得分:1)

我并不完全确定你要做什么,但假设你希望你的程序成功退出当且仅当打印成功时,你应该用C写这个:

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

int
main()
{
    if(printf("C") < 0)
      return EXIT_FAILURE;
    return EXIT_SUCCESS;
}

原因是printf将返回负数以报告错误,-1也被视为“真”。

相应的C ++程序应如下所示:

#include <cstdlib>
#include <iostream>

int
main()
{
  if (!(std::cout << "C++"))
    return EXIT_FAILURE;
  return EXIT_SUCCESS;
}

这样做的原因是<<上的调用操作符std::cout会返回对本身的引用,这也是

之类的原因。
std::cout << "You've got " << 99 << " points" << std::endl;

的工作。每次调用都会返回对std::cout的引用,然后执行下一次调用。

现在std::basic_ios std::cout派生自explicit operator bool() const; ,定义conversion operator。从C ++ 11开始,这被声明为

if

这意味着如果在布尔上下文中评估流,例如bool语句中的条件,则将其转换为boollinked page底部的表格显示返回的true将在falsetrue的条件下。总结:除非流上发生错误,否则它将返回explicit

在C ++ 11之前(当我们没有void *个运算符时),返回了一个非NULL的{​​{1}}指针,当且仅当没有错误时流发生了。同样,可以在布尔上下文中评估void *指针。

请注意,在上面显示的两个程序中,测试可能表示成功但输出仍可能失败。原因是输出通常在程序内缓冲,只有在收集到足够的输出时才会要求操作系统实际输出。您可以随时请求 flush 来实现 now 。在C中,您可以在相应的fflush指针上调用FILE *

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

int
main()
{
    if(printf("C") < 0 || fflush(stdout) < 0)
      return EXIT_FAILURE;
    return EXIT_SUCCESS;
}

在C ++中,您可以使用std::flush常量。

#include <cstdlib>
#include <iostream>

int
main()
{
  if (!(std::cout << "C++" << std::flush))
    return EXIT_FAILURE;
  return EXIT_SUCCESS;
}

如果您还想要换行符,可以使用std::endl。写

std::cout << "hello, world\n" << std::flush;

与写作

的效果大致相同
std::cout << "hello, world" << std::endl;

但请注意,出于性能原因使用输出缓冲,因此如果在每个输出语句之后定期刷新缓冲区,则可能会降低程序的性能。

最后,在C ++中,如果发生错误,您还可以要求流引发异常。由于在正常操作期间不应发生I / O错误,并且重复检查它们会使代码混乱,这可能会派上用场。

#include <cstdlib>
#include <iostream>

int
main()
{
  std::cout.exceptions(std::ifstream::failbit);
  try
    {
      std::cout << "C++" << std::flush;
      return EXIT_SUCCESS;
    }
  catch (const std::ios_base::failure &e)
    {
      return EXIT_FAILURE;
    }
}

如果要测试程序是否报告失败I / O的正确退出状态,可以尝试在POSIX系统上将标准输出管道传输到/dev/full/dev/full假装的特殊文件,因为超出了文件系统的容量,所以无法写入任何内容。

答案 3 :(得分:0)

因为这与写作相同

cout << "C++";
if(cout){
//do whatever
}

它只是写&#34; C ++&#34; cout并检查你的流是否仍然是开放的。