《C++程序设计POJ》《WEEK7 输入输出和模板》《流操纵算子》《文件读写》《二进制文件读写》
函数指针,运算符重载
人懂我精,人精我深
用的时候查一查手册
dat 二进制文件
如果不指定文件夹,就是生成在当前文件夹,什么是当前文件夹?可执行文件所在的文件夹
绝对路径
相对路径
文件的读写指针
ifstream
ofsteam
seekp()
location 可正负 , 正 往后 负代表 往开头
ios::ate 定位文件指针到文件尾
seekg()????
C++中seep()和seekg()函数功能
seekp:设置输出文件流的文件流指针位置 写指针
seekg:设置输入文件流的文件流指针位置 读指针
ios::in 读
ios::out 写
文件关闭!!!!
数据在内存缓冲区,硬盘很慢,缓冲区满了在写入到硬盘。达到打开文件上限,再也打不开文件了
ios::binary 如果不写这个会有麻烦
write(为什么是 (const char *))
/*设置域宽的流操纵算子*/ #include<iostream> #include<iomanip> using namespace std; /* 宽度设置有效性是一次性的,在每次读入和 输出之前都要设置宽度。 输入 1234567890 输出 1234 5678 90 */ int main() { int w = 4; char string[10]; cin.width(5); while (cin >> string) { cout.width(w++); cout << string << endl; cin.width(5); } }
/* 1) 8d 141 215 2) 1.2346e+006 12.346 3) 1234567.89000 12.34567 4) 1.23457e+006 1.23457e+001 */ #include<iostream> #include<iomanip> using namespace std; int main() { //1)分别以十六进制、十进制、八进制先后输出 n int n = 141; cout << "1)" << hex << n << " " << dec << n << " " << oct << n << endl; double x = 1234567.89, y = 12.34567; //2)保留 5 位有效数字 cout << "2)" << setprecision(5) << x << " " << y << " " << endl; //3)保留小数点后面 5 位 cout << "3)" << fixed << setprecision(5) << x << " " << y << endl; //4)科学计数法输出,且保留小数点后面 5 位 cout << "4)" << scientific << setprecision(5) << x << " " << y << endl; //5)非负数要显示正号,输出宽度为 12 字符,宽度不足则用 填补 cout << "5)" << showpos << fixed << setw(12) << setfill('*') << 12.1 << endl; //6)非负数不显示正号,输出宽度为 12 字符,宽度不足则右边用填充字符填充 cout << "6)" << noshowpos << setw(12) << left << 12.1 << endl; //7)输出宽度为 12 字符,宽度不足则左边用填充字符填充 cout << "7)" << setw(12) << right << 12.1 << endl; //8)宽度不足时,负号和数值分列左右,中间用填充字符填充 cout << "8)" << setw(12) << internal << -12.1 << endl; cout << "9)" << 12.1 << endl; return 0; } /* 5) ***+12.10000 6) 12.10000**** 7) ****12.10000 8) --***12.10000 9) 12.10000 */
cout << "3)" << fixed << setprecision(5) << x << " " << y << endl;
对后面所有输出都有影响??12.10000
自定义流操纵算子?
函数指针?
/* 函数指针 用户自定义流操纵算子 因为 iostream 里对 << 进行了重载 成员函数) 输出: aa bb */ #include<iostream> using namespace std; ostream &tab(ostream &output) { return output << '\t'; } int main() { cout << "aa" << tab << "bb" << endl; return 0; } /* ostream & operator<<( ostream & (*p) (ostream &) ); 该函数内部会调用p 所指向的函数,且以 *this 作为参数 */
文件读写
创建文件
•
•#include fstream > // 包含头文件
•
ofstream outFile (“clients.dat”, ios out|ios ::binary);
创建文件
–
clients.dat” 要创建的文件的名字
–
ios ::out 文件打开方式
•
ios:out 输出到文件 , 删除原有内容
•
ios ::app 输出到文件 , 保留原有内容,总是在尾部添加
–
ios ::binary 以二进制文件格式打开文件
也可以先创建 ofstream 对象,再用 open 函数打开
ofstream fout
fout.open(test.out",ios out|ios ::binary)
判断打开是否成功:
if(!fout)
{
cout<<"file open error"<<enl;
}
文件名可以给出绝对路径,也可以给相对路径。没有交代路径信息,
就是在当前文件夹下找文件
文件流 |
ios::app |
ios::ate |
||
打开方式 |
结果 |
打开方式 |
结果 |
|
ofstream (默认是ios::in | ios::trunc) |
ios::app或ios::app|ios::out |
如果没有文件,生成空文件; 如果有文件,在文件尾追加 |
ios::ate或ios::ate|ios::out |
如果没有文件,生成空文件; 如果有文件,清空该文件 |
ios::app|ios::in |
不管有没有文件,都是失败 |
ios::ate|ios::in |
如果没有文件,打开失败; 如果有文件,定位到文件尾,可以写文件,但是不能读文件 |
|
Ifstream (默认是ios::in) |
ios::app或ios::app|ios::out |
不管有没有文件,都是失败 |
ios::ate或ios::ate|ios::out |
如果没有文件,打开失败; |
ios::app|ios::in |
? |
ios::ate|ios::in |
? |
|
fstream (默认是ios::in | ios::out) |
ios::app|ios::out |
如果没有文件,创建文件; 如果有文件,在文件尾追加 |
ios::ate|ios::out |
如果没有文件,创建文件; 如果有,清空文件 |
ios::app|ios::in |
如果没有文件,失败 |
ios::ate|ios::in |
如果没有文件,失败 |
|
N/A |
N/A |
ios::ate|ios::out|ios::in |
如果没有文件,打开失败, 如果有文件,定位到文件尾 |
|
总结 |
ios::app不能和ios::in相配合, 但可以和ios::out配合,打开输入流 |
ios::ate可以和ios::in配合,此时定位到文件尾; 如果没有ios::in相配合而只是同ios::out配合,那么将清空原文件; |
||
区别 |
app会在每次写操作之前都把写指针置于文件末尾, |
而ate模式则只在打开时才将写指针置于文件末尾。在文件操作过程中,可以通过seekp等操作移动指针位置。 |
||
例子: 多个线程或者进程对一个文件写的时候,假如文件原来的内容是abc
|
以ios::app: 第一个线程(进程)往里面写了个d,第二个线程(进程)写了个e的话,结果是abcde |
以ios:ate: 后面写的会覆盖前面一个写的,第一个线程(进程)往里面写了个d,第二个线程(进程)写了个e的话,结果为abce |
/* 写一个程序,将文件 in.txt 里面的整数排序后,输出到 out.txt */ #include<iostream> #include<fstream> // file operate #include<vector> #include<algorithm> using namespace std; int main() { vector<int> v; ifstream srcFile("in.txt", ios::in); ofstream destFile("out.txt", ios::out); int x; while (srcFile >> x) { v.push_back(x); } sort(v.begin(), v.end()); for (int i = 0; i < v.size(); i++) destFile << v[i] << " "; destFile.close(); srcFile.close(); return 0; }