Make My Ostream!
2016-05-20 23:56
441 查看
Make My OStream 题解
山中何事,松花酿酒,春水煎茶Description: 自由实现代码,使得下面的代码,以及相关的代码的结果成立:所有需要待实现的东西都已经在代码中。 另外,iostream 和 sstream已经禁用,因此需要用cstdio里面的一些东西来实现效果。 已知mypres的精度不超过6 //其实也就是练习输出下面的东西 int main() { const char *test1 = "Test char"; myout << test1 << myendl; myout << test1[0]<< myendl; double e = 6.12345; int pres = 1; myout << mypres(pres*2);//setprecision(2),2位有效数字 myout << e << myendl; myout << myfixed ;//改为定点输出,即2位小数 myout << e << myendl; int d=15; myout << d << myendl; myout << myhex << d << myendl; } Sample Output Test char T 6.1 6.12 15 f Hint 不需要交main函数 Problem Source: poetry
思路一:期末复习题
这个学期学了好多东西啊..满满干货的日子快要到头了(误)..于是大大给出了一道class和流结合,官方题解为构造class来实现的神奇题目
具体”考点”如下:
运算符重载这道题明显重载左移运算符
<<,但是和模板不同的是,这道题重载左移运算符的目的不同,一般是实现流输出比如
std::cout << "Hello World" << std::endl;但是这道题重载返回的不是流,而是要求实现输出功能.
//P17 模板 friend <函数类型> operator <运算符> (形参表) { 函数体; } //一般对输出流重载 ostream& operator<< (ostream& stream,类名 &other)//重载输出流 { stream << 格式化输出内容; return stream; }
但是这道题黑掉了cout.题意也就变成了通过cstdio实现输出流
记得在SICP中,流就是一种对象
所以也就不涉及ostream了,那么对比模板和一般模板,发现可以少很多东西,所以我觉得这里是这道题的关键所在
Write function definition as normal(重载函数跟普通函数一样,具有返回类型和形参表)(课件p6)
也就是所这道题吧运算符当做函数来重载,实现一个像函数一样的功能.放这道题标准实现前,先回顾一下标准重载在这道题中的一个矛盾
函数的串联 P32
myout << test1[0]<< myendl;
上面留下的一个矛盾是,重载返回了一个流,但是新的输出函数如果返回的是
void的话就不能实现.所以这里复习了函数的串联.串联就是返回对象本身,然后本身当然可以继续调用本身的函数嘛
从前有座山,山里有个庙
所以到这里就可以概括基本实现了,由于
myout是山寨一个流对象,所以不妨把它当做一个对象,然后在这个类中实现对于不同内容的输出.
//举个栗子 /*重载运算流就是函数*/ class str { public: str &operator << (const char * a) { printf("%s",a); return *this; }; }
printf考察
很多简单的标记符比如%c,%d就不水了
但是这道题有趣的是考虑了fixed和setpresion
第一个是保留小数点后presion位,第二个是设置多少位保留
基本思路是fixed没有参量,可以直接变成一个标志的变化
setpresion需要构造一个新的类变成一个新的对象,来”暂时保存”函数值
hex的思路和fixed一样..我的实现是转化为string(“hex”)来作输出流函数然后设置标志位,输出时候判断.
//实现代码块 //忘记这次的变量命名和宏定义毁掉的代码风格QAQ //part1 define #define myendl '\n'//对我就是这么黑掉结束符的.. #define myhex string("hex") #define myfixed string("myfixed") #define mypres(n) PPP(n) class PPP //maybe an interesting name... { public: PPP(int a):pres(a){}; int pres; }; //part2 select str &operator << (string p) { if( p == string("hex")) h = true;//h is a flag for hex else if(p == string("myfixed")) f = true;//f is a flag for fixed return *this; } str &operator << (PPP k) { pre = k.pres;//pre for precision return *this; }
这里之后输出就需要判断了
输出double判断fixed,
fixed用
%.*g作为标志位,在pjr大神的题解中用sprintf来输出(fixed就是把precision的意义输出小数点后几位)
否则用
%.*lf输出即可
输出int判断hexed
一个用
%x,另一种情况用
%d
BTW..突然想起URAL居然有卡printf速度的题= =还以为是soj特色
需要注意的细节
对于<<运算符的重载,需要加&引用符,不然会不停的调用= =(某大大的形容词是不敢想象)
double输出有两个参数,一个是*的值
printf("%.*lf",pre,a);
思路二: 复制粘贴大法好
发现某学霸群大神说了句把iostream内容复制过去然后define掉..然后就跪了QAQ他的题解
源代码在编译器目录下面有
//贤城大神的代码 #include <bits/c++config.h> #include <ostream> #include <istream> #include <string> #include <cstdio> #include <algorithm> #include <cstring> #include <cstdlib> #include <vector> #include <map> #include <iomanip> using namespace std; #include <bits/c++config.h> #include <ostream> #include <istream> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION extern istream cin; /// Linked to standard input extern ostream cout; /// Linked to standard output extern ostream cerr; /// Linked to standard error (unbuffered) extern ostream clog; /// Linked to standard error (buffered) extern wistream wcin; /// Linked to standard input extern wostream wcout; /// Linked to standard output extern wostream wcerr; /// Linked to standard error (unbuffered) extern wostream wclog; /// Linked to standard error (buffered) //@} // For construction of filebuffers for cout, cin, cerr, clog et. al. static ios_base::Init __ioinit; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #define myhex hex #define myout cout #define myfixed fixed #define myendl endl #define mypres(x) setprecision(x)
Trick #undef
因为屏蔽<iostream>是通过判断#define的
//'AC'代码 #include <iostream> #include <iomanip> #define myendl endl #define myfixed fixed #define mypres(n) setprecision(n) #define myhex hex #define myout cout using namespace std; #undef _GLIBCXX_IOSTREAM
思路三(误)
上课时一直在想一个思路.然而并没有实现出来..就是cout来自iostream是继承ostream
于是就可以够着一个类似于cout的ostream,然后一切就可以顺理成章了
然后进一步发现ostream这个居然没有默认构造函数��…
需要这样来声明(来着cplusplus)
// ostream constructor #include <iostream> // std::cout, std::ostream, std::ios #include <fstream> // std::filebuf int main () { std::filebuf fb; fb.open ("test.txt",std::ios::out); std::ostream os(&fb); os << "Test sentence\n"; fb.close(); return 0; }
就是声明一个filebuf对象,然后给ostream一个它的指针
但是这里留下的疑难是怎么把stdout赋给fb或者os(也就是myout)
如果解决了后就可以用以前诗源大大helloworld系列来实现
//优先加载全局变量 ostream myout(...)//没有无参数构造函数 int f() { ... } int k = f();
~欢迎大大交流讨论
另外安利一个搜索链接,里面有谷歌的镜像.
相关文章推荐
- iostream与iostream.h的区别详细解析
- ofstream和ifstream详细用法---转
- c++ 覆盖、重载、隐藏
- 递归的简单例子 3n+1问题
- C++ 递归计算器 源代码
- C++标准库简介(转)
- 书的目录
- foj1080奇怪的数列 foj2030括号匹配
- C++简易编程---简略学生信息治 4000 理三亚艺术摄影
- thinking in c++ 卷2
- thinking in c++卷2
- thinkng in c++卷2
- Thinking in C++ 卷2中文版
- 转载:C++回调函数示例
- 解决了DEV-C++输出时一闪而过的问题
- C/C++头文件包含内容概览
- 算法系列——N皇后问题
- 数据结构实验一
- 名称空间
- 用链表来模拟堆栈