iostream头文件中4种流对象
| 对象 | 含义 | 对应设备 | 对应的类 | C语言对应文件 |
| cin | 标准输入流 | 键盘 | istream_withassign | stdin |
| cout | 标准输出流 | 控制台 | ostream_withassign | stdout |
| cerr | 标准错误流 | 控制台 | ostream_withassign | stderr |
| clog | 标准错误流 | 控制台 | ostream_withassign | stderr |
1. cout流在内存中对应开辟了一个缓存区,用来存放流中的数据,当向cout流插入一个endl时,不论缓冲区是否已满,都立即输出流中的所有数据,然后插入一个换行符,并刷新流(清空缓冲区), 注意如果插人一个换行符”\n“(如cout<<a<<"\n"),则只输出和换行,而不刷新cout 流(但并不是所有编译系统都体现出这一区别)
2.cout 流通常是传送到显示器输出,但也可以被重定向 输出到磁盘文件,而cerr流中的信息只能在显示器输出,cerr是不经过缓冲区,直接向显示器上输出有关信息,而clog中的信息存放在缓冲区中,缓冲区满后或遇endl时向显示器输出
1. 标准输入流cin
(1)常用函数
| cin.get() | 返回单个字符 |
| cin.get(char cval) | 返回单个字符 |
| cin.get(_Elem *_Str, streamsize _Count) | 返回Count字符的字符串 |
| cin.get(Elem *_Str,count, _Elem _Delim) | Delim为结尾符 |
| cin.getline(char *_Str, Count, char _Delim) | |
| cin.ignore() | 读取字符并忽略指定字符 |
| cin.peek() | 检查下一个输入的字符,不会把字符从流中移除 |
| cin.putback(char cVal) | 返回一个字符给一个流 |
1. 使用cin从流中读出的字符,流中就没有字符了,再次读取时只能读取剩下的
2. 缓冲区只有在遇到EOF、手动敲回车,流缓存区满时,才能将流中的字符全部读出(即清空缓存区)
(2)示例
#include "stdio.h" #include <iostream> using namespace std; void main() { // 从流中读取个字符然后再放进去 char cVal = cin.get(); cin.putback(cVal); // 判断流中的第一个字符是不是刚放进去的字符 if (cin.peek() == cVal) { cout << "流中的第一个字符是刚放进去的字符" << endl; } else { cout << "流中的第一个字符不是刚放进去的字符" << endl; } // 从流中读取10个字符 char cBuff[11] = {0}; cin.get(cBuff,11); // 注意这里是11 // 从流中忽略5个字符,再读取10个字符 cin.ignore(5); char cBuff1[11] = {0}; cin.get(cBuff1, 11, EOF); // 读取剩下的字符 char cBuff2[100] = {0}; cin.get(cBuff2, 100); //输出读到的数据 cout<<"第一个字符"<<cVal<<endl; cout<<"第一组 字符串:"<<cBuff<<endl; cout<<"第二组 字符串:"<<cBuff1<<endl; cout<<"剩下的字符串:"<<cBuff2<<endl; system("pause"); return; }
2. 标准输出流cout
(1)用于控制输出格式的流成员函数
| 流成员函数 | 作用相同的控制符 | 作用 |
| precision(n) | setprecision(n) | 设置实数的精度 |
| width(n) | setw(n) | 设置字符宽度 |
| fill(char cVal) | setfill(char cVal) | 设置填充字符 |
| setf() | setiosflags() | 设置输出各格式状态 |
| unsetf() | resetiosflags() | 终止已经设置的输出格式状态,在括号中应指定内容 |
(2)设置格式状态的格式标志
| 格式标志 | 作用 |
| ios::left | 输出数据在本域宽范围内向左对齐 |
| ios::right | 输出数据在本域宽范围内向右对齐 |
| ios::internal | 数值的符号位在域宽内左对齐,数值右对齐,中间由填充字符填充 |
| ios::dec | 设置整数的基数为10 |
| ios:oct | 设置整数的基数为8 |
| ios::hex | 设置整数的基数为16 |
| ios::showbase | 强制输出整数的基数(八进制以0开头,十六进制以0x开头) |
| ios::showpoint | 强制输出浮点数的小树和尾数0 |
| ios::uppercase | 以科学计数法格式E和以十六进制输出字母时以大写表示 |
| ios::showpos | 对正数显示‘+’号 |
| ios::scientific | 浮点数以科学计数法格式输出 |
| ios::fixed | 浮点数以定点格式(小数形式)输出 |
| ios::unitbuf | 每次输出之后刷新所有的流 |
| ios::stdio | 每次输出之后清除stdout/stderr |
eg : cout.setf( ios::dec );cout.setf(ios::hex,ios::basefield);【建议使用这种】
需注意:
1、fmtflags setf( fmtflags flags ); 使用这种,一定要先取消当前基【cout.unself()】,之后才可以设置新的基2、fmtflags setf( fmtflags flags, fmtflags needed ); 使用这种,第二个参数设为当前的基,或者当不知道当前基时,设为ios_base::basefield清除当前的所有可能的基
(3)输入输出流的控制符
| 控制符 | 作用 |
| dec | 设置基数10 |
| oct | 设置基数8 |
| hex | 设置基数16 |
| setfill(c) | 用字符填充 |
| setprecision(n) | 设置精度 |
| setw(n) | 设置宽度 |
| setiosflags(ios::fixed) | 设置浮点数以固定的小数位数显示 |
| setiosflags(ios::scientific) | 设置浮点数以科学计数法显示 |
| setiosflags(ios::skipws) | 忽略前导的空格 |
| setiosflags(ios::left) | 左对齐 |
| setiosflags(ios::right) | 右对齐 |
| setiosflags(ios::uppercase) | 数据以16进制输出时字母大写 |
| setiosflags(ios::lowercase) | 数据以16进制输出时字母小写 |
| setiosflags(ios::showpos) | 输出正数时给出+号 |
如果使用了控制符,需要加头文件include<iomanip>
文件输入输出流fstream
ofstream, ifstream, fstream
在头文件fstream中,在fstream类中,用open成员函数打开文件,实现类与文件的关联操作。
- open(filename, mode, prot):对所属类进行用指定的参数进行特定的文件关联
几种打开方式(mode):(这些方式可以用 '|' 组合起来)
1. 文件打开方式
| ios::in | 读文件 |
| ios::out | 写文件 |
| ios::app | 所有写入附加在文件末尾 |
| ios::ate | 打开一个已有文件,文件指针指向文件末尾 |
| ios::trunc | 打开文件,若文件存在则删除全部数据,若文件不存在则建立新文件,如已指定ios::out方式,而未指定ios::app,ios::ate,ios::in,则默认此方法 |
| ios::binary | 二进制打开文件 |
2. 属性值设置
打开文件的属性,这些方式可以用‘+’进行组合,这个参数可以省略不传
| 0 | 普通文件,打开操作 |
| 1 | 只读文件 |
| 2 | 隐含文件 |
| 4 | 系统文件 |
3. 文件状态判断
| is_open() | 文件是否正常打开 |
| bad() | 读写过程中是否出错 |
| fail() | 读写过程中是否出错 |
| eof() | 读文件到达文件末尾,返回True |
| good() | 以上任何一个返回True,这个就返回False |
4. 流指针设置
- 获得和设置流指针
- 对于所有的输入输出流都有至少一个指针,指向下一个要操作的位置
ofstream put_point
ifstream get_point
fstream put_point和get_point
- 获取流指针位置
tellg(): 返回输入流指针的位置(返回类型long)
tellp(): 返回输出流指针的位置(返回类型long)
- 设置指针位置
seekg(long position): 设置输入流指针位置为第position个字符(文件首位置为开始位置)
seekp(long position): 设置输出流指针到指定位置
istream &seekg(streamoff offset,seek_dir origin);
ostream &seekp(streamoff offset,seek_dir origin);
ios::beg: 文件开头
ios::cur: 文件当前位置
ios::end: 文件结尾
字符串输入输出流sstringstream
ostringstream:用于执行C风格字符串的输出操作
istringstream:用于执行C风格字符串的输入操作
stringstream:同时支持C风格字符串的输入输出操作
例1:
#include "stdio.h" #include <iostream> #include <sstream> using namespace std; void ostringstream_test() { ostringstream oss; oss << "this is test" << '\t'<< 123456; cout << oss.str() << endl; oss.str(""); // 清空之前的内容 // oss.clear(); // 并不能清空内存 cout << oss.str() << endl; // 浮点数转换限制 double dbVal = 123.123455677; oss << dbVal; cout << oss.str() << endl; oss.str(""); oss.precision(9); oss.setf(ios::fixed, ios::basefield); // 将浮点数的位数限定为小数点之后的位数 oss << dbVal; cout << oss.str() << endl; }
例2:
void istringstream_test() { // 输入 stringstream ss; ss << "this is test" << ' '<< 123456; cout << ss.str() << endl; // 输出 string out; while (ss >> out) { cout << out.c_str() << endl; } }
例:日志信息输出
(1)功能思维导图
(2)代码实现
#pragma once #include <stdio.h> #include <Windows.h> #define MAX_BUFFSIZE 8192 namespace Logger { enum LOGMODE { CONSOLE = 0x1, LOGFILE = 0x2, CONSOLE_FILE=0x3 }; enum LOGLEVEL { INFO = 0, DEBUG }; class CLogging { public: explicit CLogging(); explicit CLogging(const int LogMode, char *pFileName=NULL, char *pFileMode=NULL); ~CLogging(void); void LogPrintf(char* pFormat, ...); private: inline void OutputLoginfo(const char *pBuff); private: TCHAR *m_pLogFileName; TCHAR *m_pLogFileMode; int m_LogMode; FILE *m_pFile; HANDLE m_hMuex; }; }