answdl 发表于 2023-3-30 15:11

window控制台进度条(黑窗口)

头文件
#include <stdio.h>
#include <Windows.h>
控制台光标控制
void Show_Cursor(BOOL flag)
{
    CONSOLE_CURSOR_INFO curInfo = { 0 }; //定义光标信息的结构体变量
    curInfo.dwSize = sizeof(CONSOLE_CURSOR_INFO);//必须
    curInfo.bVisible = flag; //设置光标是否可见
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄
    SetConsoleCursorInfo(handle, &curInfo); //设置光标信息
}
void Set_CursorPos(SHORT x, SHORT y)
{
    COORD pos = { x,y }; //定义光标位置的结构体变量
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄
    SetConsoleCursorPosition(handle, pos); //设置光标位置
}
特殊字符打印输出
只写了两个案例
char* arr1[] = { "|", "/", "-", "\\" };//不断循环打印
char* arr2[] = { "▌" };//进度条单个字符
//加载动画
void loading(char* arr[], size_t arr_size)
{
    CONSOLE_SCREEN_BUFFER_INFO curInfo; //定义光标信息的结构体变量
    HANDLE hOuput = GetStdHandle(STD_OUTPUT_HANDLE);//获取控制台句柄
    GetConsoleScreenBufferInfo(hOuput, &curInfo);//获取光标信息
    Show_Cursor(FALSE);//隐藏光标
    for (size_t i = 0; i < 100; i++)
    {
      Set_CursorPos(curInfo.dwCursorPosition.X, curInfo.dwCursorPosition.Y);
      printf("%3zu%%:", i + 1);//占5个字符位置
      Set_CursorPos(curInfo.dwCursorPosition.X + 5 + (arr_size == 1 ? i : 0), curInfo.dwCursorPosition.Y);
      printf("%s", arr);
      Sleep(50);//任务执行
    }
    Show_Cursor(TRUE);//显示光标
    return;
}
void Progress(void)
{
    //加载
    char* arr1[] = { "|", "/", "-", "\\" };
    loading(arr1, sizeof(arr1) / sizeof(arr1));
    printf("\n");
    //进度条
    char* arr2[] = { "▌" };
    loading(arr2, sizeof(arr2) / sizeof(arr2));
    printf("\n");
    return;
}

StarMax 发表于 2024-5-11 21:30

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

// 显示/隐藏光标
void MyShowCursor(BOOL show) {
    CONSOLE_CURSOR_INFO cursorInfo;
    cursorInfo.dwSize = sizeof(CONSOLE_CURSOR_INFO);
    cursorInfo.bVisible = show;
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorInfo(handle, &cursorInfo);
}

// 设置光标位置
void SetCursorPosition(SHORT x, SHORT y) {
    COORD pos = { x, y };
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(handle, pos);
}

// 获取当前光标位置的Y坐标
int GetCurrentY() {
    CONSOLE_SCREEN_BUFFER_INFO info;
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
    return info.dwCursorPosition.Y;
}

// 显示加载动画
void ShowLoadingAnimation() {
    // 隐藏光标
    MyShowCursor(FALSE);

    // 显示加载动画
    for (int i = 0; i < 100; ++i) {
      printf("%3d%%: l", i + 1);
      Sleep(50); // 模拟任务执行
      SetCursorPosition(0, GetCurrentY()); // 回到行首
    }

    // 显示光标
    MyShowCursor(TRUE);
}

// 显示进度条
void ShowProgressBar() {
    // 隐藏光标
    MyShowCursor(FALSE);

    // 显示进度条
    for (int i = 0; i < 100; ++i) {
      printf("%3d%%: [", i + 1);
      for (int j = 0; j <= i / 2; ++j) {
            printf("=");
      }
      printf(">");
      for (int j = i / 2 + 2; j < 50; ++j) {
            printf(" ");
      }
      printf("]\r");
      Sleep(50); // 模拟任务执行
    }

    // 显示光标
    MyShowCursor(TRUE);
}

int main() {
    // 加载动画
    printf("Loading:\n");
    ShowLoadingAnimation();
    printf("\n");

    // 进度条
    printf("Progress:\n");
    ShowProgressBar();
    printf("\n");

    return 0;
}
修补后的代码

answdl 发表于 2023-4-4 19:29

MISTIS 发表于 2023-4-4 16:49
这个进度条运行的时候额外开个线程获取进度状态,影响程序效率吗?

在字符输出这里,换成一个线程原子锁之类的,等待另一个线程发消息,不会占用多少资源的
Sleep(50);//任务执行
按精确度来算,1%就是循环100次,0.1%就是1000次。。。

hairunaa 发表于 2023-3-30 15:23

原来用的utools,后来发现这个,蛮好用的

apull 发表于 2023-3-30 15:31

效果不错,多谢分享。

arujisama 发表于 2023-3-30 15:47

感觉不错,谢谢分享

BananaLi 发表于 2023-3-30 16:56

感谢分享

苍生竟何罪 发表于 2023-3-30 18:22

感谢分享,就是我想学的

Tomxuan 发表于 2023-4-4 16:30

编译不通过, 可以对着修改一下 https://blog.51cto.com/yang/3130205

goldSn0ke 发表于 2023-4-4 16:35

谁发个动画演示{:1_918:}

MISTIS 发表于 2023-4-4 16:49

这个进度条运行的时候额外开个线程获取进度状态,影响程序效率吗?
页: [1] 2
查看完整版本: window控制台进度条(黑窗口)