首页 > 代码库 > 【ThinkingInC++】72、输入输出流
【ThinkingInC++】72、输入输出流
第四章 输入输出流
Strfiile.cpp
/** * 书本:【ThinkingInC++】 * 功能:一个文件的输入输出流 * 时间:2014年10月12日15:15:59 * 作者:cutter_point */ #include <iostream> //很多平台上<fstream>会自动包含<iostream>但是不是所有 #include <fstream> #include "../require.h" using namespace std; int main() { const int SZ=100; //缓冲池的大小 char buf[SZ]; //缓冲区 { ifstream in("Strfile.cpp"); //读入文件 assure(in, "Strfile.cpp"); //确定文件被打开了 ofstream out("Strfile.txt"); //输出文件 assure(out, "Strfile.txt"); int i=1; //表示第一行 while(in.get(buf, SZ)) //读入SZ-1个字符或者,遇到'\n' { in.get(); //去除'\n',因为上面的是没有读入'\n'的,这里吧'\n'读入,但是不处理 cout<<buf<<endl; //这里必须加endl;,不然不会换行 out<<i++<<"\t: "<<buf<<endl; } } ifstream in("Strfile.txt"); assure(in, "Strfile.txt"); while(in.getline(buf, SZ)) { char* cp=buf; while(*cp != ':') //为了去除前面的序号 ++cp; cp+=2; //这是为了去除 ": " cout<<cp<<endl; } return 0; }
4.6 在输入输出流中定位
标志 功能 |
Ios::in 打开输入文件。将这种打开模式用于ofstream可以使得现存 文件不被截断 |
Ios::out 打开输出文件。 |
Ios::app 打开一个仅用于追加的输出文件 |
Ios::ate 打开一个已存在的文件,并把文件指针指向文件的末尾 如果文件存在,则截断旧文件 |
Ios::trunc 如果文件存在,则截断旧文件 |
Ios::binary 以二进制方式打开文件。默认打开为文本方式 |
read(unsigned char *buf,int num); write(const unsigned char *buf,int num);
read()从文件中读取 num 个字符到 buf 指向的缓存中,如果在还未读入 num 个字符时就到了文件尾,可以用成员函数 int gcount()来取得实际读取的字符数;而 write() 从buf 指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是 unsigned char *,有时可能需要类型转换。
* seekg() 对输入文件定位,有两个参数:
* 第一个:表示偏移量,可正可负,正表示向后,负表示向前
* 第二个:偏移的基地址,可以是:
* ios::beg 输入流的开始
* ios::cur 输入流的当前位置
* ios::end 输入流的结束
4.7 字符串输入输出流
ws指的是std::ws,是用来去除空格的
比如:
int i; float f; char buf[100]; cin >> i >> f; cin >> std::ws; cin.getline(buf, 100);
这段程序在运行时,你需要输入一个整形数,然后输入一个空格,再输入一个浮点数。然后,你可以输入若干空格,最后输入字符串。
cin在读取到整数和浮点数之后,会继续读取你输入的字符串,并且忽略浮点数和字符串之间的若干空格。
Ostring.cpp
/** * 书本:【ThinkingInC++】 * 功能:输出字符串流 * 时间:2014年10月12日15:17:02 * 作者:cutter_point */ #include <iostream> #include <sstream> #include <string> using namespace std; int main() { cout<<"输入一个int,一个float,一串字符串"; int i; float f; cin>>i>>f; cin>>ws; //去除空格,ws是std里面的,为了忽略空格的 string stuff; getline(cin, stuff); //得到一行字符串 ostringstream os; //字符串输出流 os<<"integer = "<<i<<endl; os<<"float = "<<f<<endl; os<<"string = "<<stuff<<endl; string result=os.str(); cout<<result<<endl; return 0; }
4.8 输入流的格式化
开/关标志 | 作用 |
Ios::skipws | 跳过空格 |
Ios::showbase | 打印整数值的时候指出数字的基数 |
Ios::showpoint | 显示浮点值得小数点并截断数字末尾的0 |
Ios::uppercase | 显示十六进制值时使用大写A~F,显示科学计数中的E |
Ios::showpos | 显示正数前的加号(+) |
Ios::unitbuf | “单元缓冲区”。每次插入后刷新 |
Ios::basefield | 作用 |
Ios::dec | 十进制 |
Ios::hex | 十六进制 |
Ios::oct | 八进制 |
Ios::floatfield | 作用 |
Ios::scientific | 以科学计数法形式显示浮点数 |
Ios::fixed | 以固定格式显示浮点数 |
“automatic” | 精度域指示所有有效数字的位数 |
Ios::adjustfield | 作用 |
Ios::left | 数值左对齐 |
Ios::right | 右对齐 |
Ios::internal | 前面的正负号左对齐,后面数值右对齐 |
函数 | 作用 |
Int ios::width() | 返回当前宽度。默认为0 |
Int ios::width(int n) | 设定宽度,并返回当前宽度 |
Int ios::fill() | 返回当前填充字符,默认是空格 |
Int ios::fill(int n) | 设定填充字符,并返回前面的字符 |
Int ios::precision() | 返回当前浮点数精度 |
Int ios::precision(int n) | 设定浮点数精度,返回先前的精度。 |
Format.cpp
/** * 书本:【ThinkingInC++】 * 功能:关于一些格式化域的使用 * 时间:2014年10月12日15:17:35 * 作者:cutter_point */ #include <iostream> #include <fstream> using namespace std; #define D(A) T<<#A<<endl; A //D(A)代表先执行后面那个,然后还要执行A代表的意思 int main() { ofstream T("format.txt"); D(int i=47); D(float f=123456789.543235453); const char* s="I`m cutter_point"; D(T.setf(ios::unitbuf);) //“单元缓冲区”。每次插入后刷新 D(T.setf(ios::showbase);) //打印整数值的时候指出数字的基数 D(T.setf(ios::uppercase | ios::showpos);) D(T<<i<<endl;) //默认是10进制 D(T.setf(ios::hex, ios::basefield);) D(T<<i<<endl;) D(T.setf(ios::oct, ios::basefield);) D(T<<i<<endl;) D(T.unsetf(ios::showbase);) //打印整数值的时候指出数字的基数 D(T.setf(ios::dec, ios::basefield);) D(T.setf(ios::left, ios::adjustfield);) //数值左对齐 D(T.fill('0');) D(T<<"fill char: "<<T.fill()<<endl;) D(T.width(10);) T<<i<<endl; //右对齐 D(T.setf(ios::right, ios::adjustfield);) D(T.width(10);) T<<i<<endl; //前面的正负号左对齐,后面数值右对齐 D(T.setf(ios::internal, ios::adjustfield);) D(T.width(10);) T<<i<<endl; D(T<<i<<endl;) D(T.unsetf(ios::showpos);) D(T.setf(ios::showpoint);) D(T<<"prec = "<<T.precision()<<endl;) //设定浮点数精度,返回先前的精度。 D(T.setf(ios::scientific, ios::floatfield);) D(T<<endl<<f<<endl;) D(T.unsetf(ios::uppercase);) D(T<<endl<<f<<endl;) D(T.setf(ios::fixed, ios::floatfield);) //以固定格式显示浮点数 D(T<<f<<endl;) D(T.precision(20);) D(T<<"prec = "<<T.precision()<<endl;) //设定浮点数精度,返回先前的精度。 D(T<<endl<<f<<endl;) D(T.setf(ios::scientific, ios::floatfield);) D(T<<endl<<f<<endl;) D(T.setf(ios::fixed, ios::floatfield);) //以固定格式显示浮点数 D(T<<f<<endl;) D(T.width(10);) T<<s<<endl; D(T.width(40);) T<<s<<endl; D(T.setf(ios::left, ios::adjustfield);) D(T.width(40);) T<<s<<endl; return 0; }
4.9 操纵算子
操纵算子 | 作用 |
Showbase | 输出整形数时显示数字的基数(dec, oct或hex) |
Noshowbase |
|
Showpos | 显示正数前面的正号(+) |
Noshowpos |
|
Uppercase | 用大写的A~F显示十六进制数,在科学计数型数字中使用大写的E |
Nouppercase |
|
Showpoint | 显示浮点数的十进制小数点和尾部的0 |
Noshowpoint |
|
Skipws | 跳过输入中的空格 |
Noskipws |
|
Left | 数值左对齐 |
Right | 右对齐,向左边填充字符 |
Internal | 把填充字符放到引导符或基数指示符和数值之间 |
Scientific | 指出浮点数的优先输出格式 |
Fixed |
|
4.9 操作算子
4.9.3 效用算子
自己创建算子。
Effector.cpp
/** * 书本:【ThinkingInC++】 * 功能:效用算子 * 时间:2014年10月12日15:18:32 * 作者:cutter_point */ #include <cassert> #include <limits> #include <sstream> #include <string> #include <iostream> using namespace std; class Fixw { string str; public: Fixw(const string& s, int width) : str(s, 0, width) {} friend ostream& operator<<(ostream& os, const Fixw& fw) { return os<<fw.str; } }; typedef unsigned long ulong; //二进制输出 class Bin { ulong n; public: Bin(ulong nn) { n=nn; } friend ostream& operator<<(ostream& os, const Bin& b) { const ulong ULMAX=numeric_limits<ulong>::max(); ulong bit=~(ULMAX>>1); while(bit) { os<<(b.n & bit ? '1' : '0'); bit>>=1; } return os; } }; int main() { string words="C++ that make us happy, make us wise"; for(int i=words.size() ; --i >= 0 ;) { ostringstream s; //输出流 s<<Fixw(words, i); assert(s.str() == words.substr(0, i)); cout<<s.str()<<endl; } ostringstream xs, ys; xs<<Bin(0xCAFEBABEUL); cout<<xs.str()<<endl; ys<<Bin(0x76543210UL); cout<<ys.str()<<endl; return 0; }
【ThinkingInC++】72、输入输出流