相关文章推荐
大气的香槟  ·  mysql ...·  4 月前    · 
礼貌的机器人  ·  C# ...·  11 月前    · 
俊秀的排球  ·  SqlServer ...·  1 年前    · 

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;
        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清除当前的所有可能的基

文件输入输出流fstream

  ofstream, ifstream, fstream

  在头文件fstream中,在fstream类中,用open成员函数打开文件,实现类与文件的关联操作。

  - open(filename, mode, prot):对所属类进行用指定的参数进行特定的文件关联

              几种打开方式(mode)(这些方式可以用 '|' 组合起来)

1. 文件打开方式

ios::in

      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风格字符串的输入输出操作

#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;
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)代码实现

Logging.h
#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;
Logging.cpp
#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;
StopWatch.h
#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;
test.cpp
#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;