huidong

首页 | 会员登录 | 关于争取 2022 寒假做出汇东网 Ver3.0.0 !
搜索文章



源码:

/*
*
*   PrintfWithBuffer.h
*
*   带有缓冲的printf
*   可以避免大量printf带来的闪烁
*
*    by huidong 2020.7.21 <mailkey@yeah.net>
*
*/


#pragma once

#include <stdio.h>
#include <Windows.h>

namespace cmd_buffer
{
    // cmd 缓冲输出存储器
    char* m_cmd_buffer = NULL;

    // 缓冲器大小
    UINT m_buffer_size = 0;

    // 设置光标位置
    void Gotoxy(int x, int y)
    {
        COORD coord;
        coord.X = x;
        coord.Y = y;
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); // 移动光标
    }

    // 初始化cmd缓冲器
    //
    // size 缓冲内容最大长度(字节)
    void InitCMDBuffer(UINT size = 1024000)
    {
        m_buffer_size = size;
        m_cmd_buffer = new char[size + 1];
        sprintf_s(m_cmd_buffer, size, "");
    }

    // 关闭cmd缓冲器
    void CloseCMDBuffer()
    {
        delete[] m_cmd_buffer;
        m_cmd_buffer = NULL;
        m_buffer_size = 0;
    }

    // 输出缓冲区内容
    void FlushCMDBuffer()
    {
        Gotoxy(0, 0);
        printf("%s", m_cmd_buffer);
    }

    // 将内容输出至缓冲区
    void BufferPrint(const char* _Format, ...)
    {
        // 可变参列表
        va_list list;
        va_start(list, _Format);

        // 存储可变参部分的值
        char* str_temp_beffer = new char[m_buffer_size + 1];

        // 将可变参的值写入临时变量
        vsprintf_s(str_temp_beffer, m_buffer_size, _Format, list);
        // 写入总缓冲区
        sprintf_s(m_cmd_buffer, m_buffer_size, "%s%s", m_cmd_buffer, str_temp_beffer);

        delete[] str_temp_beffer;

        va_end(list);
    }

    // 清空缓冲区
    void ClearBuffer()
    {
        if (m_cmd_buffer != NULL)
        {
            sprintf_s(m_cmd_buffer, m_buffer_size, "");
        }
    }
}


using cmd_buffer::InitCMDBuffer;
using cmd_buffer::CloseCMDBuffer;
using cmd_buffer::FlushCMDBuffer;
using cmd_buffer::BufferPrint;
using cmd_buffer::ClearBuffer;


使用示例:

#include "PrintfWithBuffer.h"

int main()
{
    InitCMDBuffer();

    int i = 20;
    char str[] = "hello";
    BufferPrint("%d is a num and \'%s\' isn\'t a num.", i, str);

    FlushCMDBuffer();

    CloseCMDBuffer();

    while (true);

    return 0;
}


输出:

图片.png



BufferPrint是支持可变参的,所以printf函数可以直接换成BufferPrint函数。

你只需要在开启缓冲输出之前 InitCMDBuffer(); 进行初始化一下,就可以调用BufferPrint函数了。

调用完BufferPrint,你需要使用 FlushCMDBuffer 函数输出存储在缓冲区的内容。

最后,使用完时,记得 CloseCMDBuffer 结束缓冲输出。


另外,由于缓冲区大小有限,建议使用ClearBuffer函数清空缓冲区。




返回首页


Copyright (C) 2018-2024 huidong