huangfu Blog
Love Leanote!
Toggle navigation
huangfu Blog
主页
About Me
归档
标签
15IO流
2017-03-02 21:32:48
142
0
0
tarena
#IO流 ##什么叫输入输出? 输入输出都是`相对内存`而言的 * 输入就是从外部输入到内存中 * 输出就是从内存输出到外部的 ##标准输入输出对象 cout 有缓冲 可以直接重定向 cerr 无缓冲 不能直接重定向 clog 和编译器有关 不能直接重定向 cin ##UC那点东西 system(const char* cmd); // 可以执行终端中的指令 0 标准输入 1 标准输出 2 标准错误 > find / -name a.txt 2>/dev/null "在根目录下查找a.txt文件,并把标准错误丢弃到空设备中 cat /dev/null a.txt "清空文件 ##类的继承层次 ![](https://leanote.com/api/file/getImage?fileId=58b2e590ab644107b2004106) * 操作控制台: cin cout --------> `#include <iostream>` 类istream 类ostream * 操作文件 ------------> `#include <fstream>` 类ifstream 类ofstream 类fstream * 操作字符串 -----------> `#include <sstream>` 类ostringstream 类istringstream ##IO的格式化和非格式化 * 格式化IO会忽略一切空白和换行 如C语言的scanf,printf, c++的输入输出运算符 << >> * 非格式化换行把所有的一切当做字符处理,如空行,空格换行等等 如C++的get(),put() 代码 #include <iostream> using namespace std; /* 输入什么就输出什么,包括空格回车*/ int main() { int c; while(1) { c = cin.get(); cout.put(c); } } ##非格式化IO ###文件IO 因为类fstream继承了iostream,也就是fstream是iostream的子类,所以自然而然继承了get(),put()等函数 > int get(); // 返回EOF代表文件尾 istream& get(char& ch); // 流本身不是NULL,是NULL代表结束 ostream& put(char ch); // 写一个字符 /* 读取一个文件,读一个字符打印一个字符/ #include <iostream> #include <fstream> #include <string> using namespace std; int main() { string filename = "03ifstream_get.cpp"; /* 创建ifstream流的类*/ ifstream ifs(filename.c_str()); if(!ifs) { cout << "打开文件失败" << endl; } /* 第一种写法*/ int c; while((c = ifs.get() != EOF) { cout.puc(c); } ifs.close(); /* 第二种写法*/ char c; while(ifs.get(c)) { cout.put(c); } ifs.close(); } 读取行 > istream& getline(char* buffer, streamsize num); // 最多能成功录入num - 0 个字符 > istream& getline(char* buffer, streamsize num, char delim); 当录入超出后流就出错了,流出错后就会拒绝IO,并流的地址变为0 可以手动让流复位,使用clear()函数 clear()函数不会清空缓冲区,所以经常需要和清理缓冲区函数ignore()函数配合使用 > clear(); // 使流复位 > ignore(int num, char deli); // 读取缓冲区(作用是清理缓冲,忽略缓冲) 代码 #include <iostream> using namespace std; int main() { char data[10]; cout << cin << endl; cin.getline(data,9); /* 如果输入字符超过9,则会使IO出错,流的地址变为0*/ cout << cin << endl; /* 如果流出错,需要复位流,并清理缓冲区*/ if(!cin) { cin.clear(); cin.ifnore(200, '\n'); } int age = 123; cin > age; cout << age << endl; } 文件操作: 读取配置文件config.txt `config.txt:` serverip=192.168.1.5 port=9987 conncount=500 pct=85.76 `read_config_txt.cpp:` #include <iostream> #include <fstream> using namespace std; int main() { ifstream ifs("config.txt"); if(!ifs) { cout << "打开文件失败" << endl; return -1; } char temp[100]; char serverip[20]; short port; int conncount; double pct; ifs.getline(temp,100,'='); ifs.getline(serverip,19); ifs.getline(temp,100,'='); ifs >> port; // 格式化读取 ifs.getline(temp,100,'='); ifs >> counncount; // 格式化读取 ifs.getline(temp,100,'='); ifs >> pct; // 格式化读取 ifs.close(); cout << serverip << ':' << port << ':' << counncount << ':' << pct << endl; } ###其他非格式化IO > peek(); //偷看下一个字符 ... ... ##字符串IO `string + += 只能拼接字符串或者string`,但是不能按照格式进行拼接,也就是sprintf()函数相同功能. C++使用`ostringstream`构建对象,使用`输出运算符`把数据存入这个对象,使用`成员函数str()`把该对象变成字符串,`达到sprintf的效果`. #include <iostream> #include <string> #include <sstream> using namespace std; int main() { string name = "test"; int age = 20; double salary = 8875.8; ostringstream ostr; ostr << name << ':' << age << ':' << salary; cout << ostr.str() << endl; } ###例子 /* 制作日记文件名*/ #include <iostrea> #include <ctime> #include <sstream> #include <iomanip> using namespace std; int main() { time_t t = time(NULL); struct tm* mytm - localtime(&t); ostringstream ostr; ostr << mytm->tm_year + 1900 << '-' << setfill('0') << setw(2) << mytm->tm_mon << '-' << setw(2) << mytm->tm_day << ' ' << setw(2) << mytm->tm_hour << ':' << setw(2) << mytm->tm_min << ':' << setw(2) << mytm->tm_sec << "data.log"; cout << ostr.str() << endl; } ###如何让ostringstream对象可以接收自定义类的对象??? 重载这个对象对应类型的输出运算符 #include <iostream> #include <sstream> #include <iomanip> using namespace std; class Date { int year; int mon; int day; public: Date(int year = 2017, int mon = 2, int day = 28) :year(year),mon(mon),day(day) { } friend ostream& operator<<(ostream& os, const Date date) { return os << date.year << '-' << setfill('0') << setw(2) << date.mon << '-' << setw(2) << date.day; } }; int main() { Date date; ostringstream ostr; /* 多肽的威力*/ ostr << date; cout << ostr.str() << endl; } ###字符串的输入流 `istringstream`就是数据来自于这个对象,使用输入运算符可以自动解析出相应的数据 #include <iostream> #incldue <sstream> using namespace std; int main() { istringstream istr("minwei 40 88888"); string name; int age; double salary; istr >> name >> age >> salary; cout << name << ':' << age << ':' << salary << endl; // minwei:40:88888 } ##文件的输入输出 ###文件的读写 > ostream& write(const char* buffer, streamsize num); > isream& read(char* buffer, streamsize num); > streamsize gcount() const; // 获取实际读取到的个数 例子代码 #include <iostream> #include <string> #include <cstring> #include <fstream> using namespace std; class Dog { char name[20]; int age; public: Dog(string name = " ", int age = 0) { strcpy(this->name, name.c_str()); this->age = age; } void show() { cout << name << ':' << age << endl; } }; int main() { Dog doga("wangcai", 2); Dog dogb("xiaohei", 3); ofstream ofs("dog.dat"); if(!ofs) { cout << "open file failed" << endl; return -1; } ofs.write((char*)&doga, sizeof doga); ofs.write((char*)&dogb, sizeof dogb); ofs.close(); /* 运行以上代码,得到一个dog.dat的文件,文件大小为48*/ ifstream ifs("dog.dat"); if(!ifs) { cout << "open file failed" << endl; return -1; } Dog dogc; ifs.read((char*)&dogc, sizeof dogc); dogc.show(); // wangcai:2 char buffer[100]; ifs.read(buffer, sizeof buffer); /* gcount()函数返回实际读取到的个数*/ cout << ifs.gcount() << endl; // 24 } ###随机读取 > istream& seekg(off_type offset, ios::seekdir origin); // 调整读指针 > ostream& seekp(off_type offset, ios::seekdir origin); // 调整写指针 > 参考点origin: ios::beg ios::end ios::cur > pos_type tellg(); // 定位读的文件指针位置 > pos_type tellp(); // 定位写的文件指针位置 例子代码 #include <iostream> #include <fstream> using namespac std; int main() { /* 如果该文件不存在,不会自动创建*/ fstream iofs("random.txt"); if(!iofs) { cout << "open file failed" << endl; return -1; } 不管的tellp得到的还是tellg得到的文件指针永远是一个,因为文件指针本身就是一个,不管读还是写*/ cout << iofs.tellp() << endl; // 0 cout << iofs.tellg() << endl; // 0 iofs << "hello"; cout << iofs.tellp() << endl; // 5 cout << iofs.tellg() << endl; // 5 /* 这里123会被解析成字符串,而不是整数,要注意*/ iofs << 123; cout << iofs.tellp() << endl; // 8 cout << iofs.tellg() << endl; // 8 iofs << "test"; cout << iofs.tellp() << endl; // 12 cout << iofs.tellg() << endl; // 12 iofs.seekp(-6, ios::cur); cout << iofs.tellp() << endl; // 6 cout << iofs.tellg() << endl; // 6 iofs << "bc"; iofs.close(); /* 最后文件中的内容: hello1bctest */ } ####小细节 ofstream ofs("a.txt"); // 如果该文件不存在则创建 ifstream ifs("a.txt"); // 如果该文件不存在,则不会创建,流为NULL fstream iofs("a.txt"); // 如果文件不存在,则不会创建,流为NULL ##C++ IO 中的格式化控制 `cout << boolalpha << f << endl; setfill('0'); setw(2); ------> #include <iomaniip> ... ... ` C语言的格式控制比C++的格式控制简洁好用 ##综合例子 写一个程序,读取一个文件的内容,把读取的内容的每一个字符和同一个随机字符进行异或, 然后把这个简单加密的内容写入另外一个文件,当然传对异或的字符对加密的文件解密. `filetools a.txt b.txt` 这就是把a.txt文件加密成 b.txt文件 `filetools b.txt c.txt Key` 这就是把b.txt解密成c.txt,key是一个0-255之间的数字 ##还需要什么? [C/C++参考手册](http://en.cppreference.com/w/) http://en.cppreference.com/w/
上一篇:
10继承(构造,析构,拷贝构造,赋值运算符)/名字隐藏机制
下一篇:
14异常exception
0
赞
142 人读过
新浪微博
微信
腾讯微博
QQ空间
人人网
提交评论
立即登录
, 发表评论.
没有帐号?
立即注册
0
条评论
More...
文档导航
没有帐号? 立即注册