- 论坛徽章:
- 0
|
写出和下面C代码相同功能的C++代码
要求:
1、不查阅参考手册(很基本的格式化输出而已)
2、使用cout对象
- #include <stdio.h>
- int main()
- {
- int i;
- float f;
- for (i = 0; i < 4; i++)
- printf("%4d|", i);
- printf("\n");
- for (i = 0; i < 4; i++)
- printf("%-4d|", i);
- printf("\n");
- for (i = 0; i < 4; i++)
- printf("%04d|", i);
- printf("\n");
- printf("\n");
- f = 3.14;
- for (i = 0; i < 4; i++)
- printf("%.4f|", f);
- printf("\n");
- for (i = 0; i < 4; i++)
- printf("%8.4f|", f);
- printf("\n");
- for (i = 0; i < 4; i++)
- printf("%8.4-f|", f);
- printf("\n");
- return 0;
- }
复制代码
感谢tyc给出的相同功能的c++版本:
PS:看了tyc的解答后,我就感到后悔了,应该这么出的:
- printf("%04d, %8.3f", 123, 3.14);
复制代码
一定会让使用cout的人吐血的,呵呵。
- #include <iostream>
- #include <iomanip>
- using namespace std;
- int main()
- {
- for (int i = 0; i < 4; ++i)
- cout << setw(4) << i << '|';
- cout << '\n';
- cout << left;
- for (int i = 0; i < 4; ++i)
- cout << setw(4) << i << '|';
- cout << '\n';
- cout << right;
- cout << setfill('0');
- for (int i = 0; i < 4; ++i)
- cout << setw(4) << i << '|';
- cout << '\n';
- cout << setfill(' ');
- cout << '\n';
- const float f = 3.14f;
- cout << fixed;
- cout << setprecision(4);
- for (int i = 0; i < 4; ++i)
- cout << f << '|';
- cout << '\n';
- for (int i = 0; i < 4; ++i)
- cout << setw(8) << f << '|';
- cout << '\n';
- cout << left;
- for (int i = 0; i < 4; ++i)
- cout << setw(8) << f << '|';
- cout << '\n';
- cout << right;
- cout.unsetf(ios_base::floatfield);
- }
复制代码
程序输出:
附录:google c++编程风格指南
流(Streams):只在记录日志时使用流。
定义:
流是printf()和scanf()的替代。
优点:
有了流,在输出时不需要关心对象的类型,不用担心格式化字符串与参数列表不匹配(虽然在gcc中使用printf也不存在这个问题),打开、关闭对应文件时,流可以自动构造、析构。
缺点:
流使得pread()等功能函数很难执行,如果不使用printf之类的函数而是使用流很难对格式进行操作(尤其是常用的格式字符串%.*s),流不支持字符串操作符重新定序(%1s),而这一点对国际化很有用。
结论:
不要使用流,除非是日志接口需要,使用printf之类的代替。使用流还有很多利弊,代码一致性胜过一切,不要在代码中使用流。
拓展讨论:
对这一条规则存在一些争论,这儿给出深层次原因。回忆唯一性原则(Only One Way):我们希望在任何时候都只使用一种确定的I/O类型,使代码在所有I/O处保持一致。因此,我们不希望用户来决定是使用流还是printf + read/write,我们应该决定到底用哪一种方式。把日志作为例外是因为流非常适合这么做,也有一定的历史原因。
使用流易造成的错误:
流的支持者们主张流是不二之选,但观点并不是那么清晰有力,他们所指出流的所有优势也正是其劣势所在。流最大的优势是在输出时不需要关心输出对象的类型,这是一个亮点,也是一个不足:很容易用错类型,而编译器不会报警。使用流时容易造成的一类错误是:
- cout << this; // Prints the address
- cout << *this; // Prints the contents
复制代码
编译器不会报错,因为<<被重载,就因为这一点我们反对使用操作符重载。
可读性比较:
有人说printf的格式化丑陋不堪、易读性差,但流也好不到哪儿去。看看下面两段代码吧,哪个更加易读?
- cerr << "Error connecting to '" << foo->bar()->hostname.first
- << ":" << foo->bar()->hostname.second << ": " << strerror(errno);
复制代码
- fprintf(stderr, "Error connecting to '%s:%u: %s",
- foo->bar()->hostname.first, foo->bar()->hostname.second, strerror(errno));
复制代码
你可能会说,“把流封装一下就会比较好了”,这儿可以,其他地方呢?而且不要忘了,我们的目标是使语言尽可能小,而不是添加一些别人需要学习的新的内容。
总结:
每一种方式都是各有利弊,“没有最好,只有更好”,简单化的教条告诫我们必须从中选择其一,最后的多数决定是printf + read/write。
[ 本帖最后由 CRLF 于 2009-2-9 20:39 编辑 ] |
|