大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。
输入输出流类关系图
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; }; }
#include "Logging.h" #include <time.h> namespace Logger { CLogging::CLogging(void) { m_pLogFileName = NULL; m_pLogFileMode = NULL; m_pFile = NULL; m_hMuex = NULL; } CLogging::CLogging( const int LogMode, char *pFileName, char *pFileMode ): m_LogMode(LogMode),m_pLogFileName(pFileName),m_pLogFileMode(pFileMode) { m_hMuex = CreateMutex(NULL, 0, NULL); m_pFile = NULL; switch (LogMode) { case CONSOLE: break; case LOGFILE: case CONSOLE_FILE: { m_pFile = fopen(m_pLogFileName, pFileMode); if (!m_pFile) { throw ("Open LogFile Error!"); } } break; } } CLogging::~CLogging(void) { if (m_pFile) { fclose(m_pFile); } if (m_hMuex!=NULL) { CloseHandle(m_hMuex); } } void CLogging::LogPrintf(char* pFormat, ... ) { DWORD nRet = WaitForSingleObject(m_hMuex, 5000); switch (nRet) { case WAIT_OBJECT_0: { va_list args; char cText[MAX_BUFFSIZE] = {0}; va_start(args, pFormat); vsprintf(cText, pFormat, args); OutputLoginfo(cText); va_end(args); ReleaseMutex(m_hMuex); } break; case WAIT_TIMEOUT: break; case WAIT_FAILED: break; } } inline void CLogging::OutputLoginfo( const char *pBuff ) { time_t CurrentTime; time(&CurrentTime); char TimeBuff[MAX_PATH] = {0}; char cBuff[MAX_BUFFSIZE] = {0}; // 根据日志级别的不同配置不同的显示信息 strftime(TimeBuff, sizeof(TimeBuff), "%H:%M:%S",localtime(&CurrentTime) ); //sprintf_s(cBuff, MAX_BUFFSIZE, "[%s] [%s: %s] %d entered\n %s", TimeBuff, __FILE__, __FUNCTION__, __LINE__, pBuff); sprintf_s(cBuff, MAX_BUFFSIZE, "[%s] [%s:] %d entered\n %s", TimeBuff, __FUNCTION__, __LINE__, pBuff); switch (m_LogMode) { case CONSOLE: printf(cBuff); break; case LOGFILE: fputs(cBuff, m_pFile); break; case CONSOLE_FILE: printf(cBuff); fputs(cBuff, m_pFile); break; } } }
#pragma once namespace Logger { class CStopwatch { private: // 64位有符号整数可以用INT64 _int64 LARGE_INTEGER表示 LARGE_INTEGER m_nPerfFrequency; LARGE_INTEGER m_nPerFrefStart; public: CStopwatch(){QueryPerformanceFrequency(&m_nPerfFrequency); Start();} inline void Start(){QueryPerformanceCounter(&m_nPerFrefStart);} inline INT64 Now() const { LARGE_INTEGER nPerfNow; QueryPerformanceCounter(&nPerfNow); return ((nPerfNow.QuadPart - m_nPerFrefStart.QuadPart) * 1000) / m_nPerfFrequency.QuadPart; } inline INT64 NowInMicro() const { LARGE_INTEGER nPerfNow; QueryPerformanceCounter(&nPerfNow); return ((nPerfNow.QuadPart - m_nPerFrefStart.QuadPart) * 1000000) / m_nPerfFrequency.QuadPart; } }; }
#include "stdio.h" #include "Logging.h" #include "StopWatch.h" using namespace Logger; #include <iostream> using namespace std; bool bThead1 = false; bool bThead2 = false; void TestFun1() { CLogging log(CONSOLE|LOGFILE, "D:\\testlog.txt", "a+"); for (int i = 0 ; i < 100; i ++) { log.LogPrintf("%s 0x%0x\n", "hello", i); } } void TestFun2() { CLogging log(CONSOLE|LOGFILE, "D:\\testlog.txt", "a+"); for (int i = 101 ; i < 200; i ++) { log.LogPrintf("%s %0x\n", "hello", i); } } DWORD WINAPI ThreadFun1(LPVOID lparam) { TestFun1(); cout << "thread1 end" << endl; bThead1 = true; return 0; } DWORD WINAPI ThreadFun2(LPVOID lparam) { TestFun2(); cout << "thread2 end" << endl; bThead2 = true; return 0; } int main() { CStopwatch watch; //TestFun(); 单线程测试 // 多线程测试 DWORD lpThreadId1 = 0; DWORD lpThreadId2 = 1; HANDLE hThread1 = CreateThread(NULL, 0, ThreadFun1, NULL, 0, &lpThreadId1); //HANDLE hThread2 = CreateThread(NULL, 0, ThreadFun2, NULL, 0, &lpThreadId2); while(1) { if (bThead1 && bThead2) { break; } } cout <<"共用时:"<< watch.Now()<<"ms" << endl; return 0; }
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/120178.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...