我写了这个简单的程序。我知道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;
}
答案 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
语句中的条件,则将其转换为bool
。 linked page底部的表格显示返回的true
将在false
或true
的条件下。总结:除非流上发生错误,否则它将返回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并检查你的流是否仍然是开放的。