【问题标题】:How to make a loading animation in Console Application written in C++?如何在用 C++ 编写的控制台应用程序中制作加载动画?
【发布时间】:2011-12-13 08:24:46
【问题描述】:

我正在用 c++ 编写一个控制台应用程序,我需要使用 ASCII 字符来制作类似“loading.gif”的东西。

以下是我应该使用的字符列表:

  1. --
  2. \
  3. |
  4. /
  5. --

这些符号将通过循环制作加载动画。

但是,当我写输出时,它变成了:

输出第一行: -- 输出第 2 行: \ 输出第 3 行: | 输出第 4 行: / 输出第 5 行: --

我需要这样做:

输出第 1 行: [这将一直被替换]

它不应该进入第二行。

如何在 C++ 中做到这一点?有没有替换功能?

【问题讨论】:

标签: c++ animation console replace loading


【解决方案1】:

您可以使用退格字符 ('\b') 返回并覆盖控制台上的字符。您还需要在每次更改后刷新输出,否则输出可能会保留在缓冲区中而不会出现在控制台上。

这是一个简单的例子:

#include <iostream>
#include <unistd.h> // for sleep()

int main()
{
    std::cout << '-' << std::flush;
    for (;;) {
        sleep(1);
        std::cout << "\b\\" << std::flush;
        sleep(1);
        std::cout << "\b|" << std::flush;
        sleep(1);
        std::cout << "\b/" << std::flush;
        sleep(1);
        std::cout << "\b-" << std::flush;
    }
}

【讨论】:

  • 在 osx(可能还有 *nix/任何 unicode 控制台)上 "\b" 打印一个颠倒的 ?
  • @MatthewClark:这很奇怪。它在我的 Linux bash 控制台上按预期工作。
【解决方案2】:

Microsoft Windows 版本。

#include <iostream>
#include <windows.h> // for sleep()

int main()
{
    std::cout << '-' << std::flush;
    for (;;) {
        Sleep(10);
        std::cout << "\b\\" << std::flush;
        Sleep(10);
        std::cout << "\b|" << std::flush;
        Sleep(10);
        std::cout << "\b/" << std::flush;
        Sleep(10);
        std::cout << "\b-" << std::flush;
    }

    return 0;
}

【讨论】:

    【解决方案3】:

    使用了 Mike Seymour 的逻辑,但外观逼真。

    #include <iostream>
    #include <unistd.h> // for sleep()
    
    int main()
    {
    
        std::cout << "Loading Please Wait";
        while (true)
        {
            sleep(1);
            std::cout << "." << std::flush;
            sleep(1);
            std::cout << "." << std::flush;
            sleep(1);
            std::cout << "." << std::flush;
            sleep(1);
            std::cout << "\b\b\b   \b\b\b" << std::flush;
        }
    }
    

    【讨论】:

      【解决方案4】:
      #include <iostream>
      #include <stdio.h>
      #include <windows.h>
      
      int main()
      {
          for (;;) {
      
              std::cout << "\b\b\b\b\b\b\b\b\b\bLoading   " << std::flush;
              Sleep(100);
              std::cout << "\b\b\b\b\b\b\b\b\b\bLOading   " << std::flush;
              Sleep(100);
              std::cout << "\b\b\b\b\b\b\b\b\b\bLoAding   " << std::flush;
              Sleep(100);
              std::cout << "\b\b\b\b\b\b\b\b\b\bLoaDing   " << std::flush;
              Sleep(100);
              std::cout << "\b\b\b\b\b\b\b\b\b\bLoadIng   " << std::flush;
              Sleep(100);
              std::cout << "\b\b\b\b\b\b\b\b\b\bLoadiNg   " << std::flush;
              Sleep(100);
              std::cout << "\b\b\b\b\b\b\b\b\b\bLoadinG   " << std::flush;
              Sleep(100);
              std::cout << "\b\b\b\b\b\b\b\b\b\bLoading.  " << std::flush;
              Sleep(100);
              std::cout << "\b\b\b\b\b\b\b\b\b\bLoading.." << std::flush;
              Sleep(100);
              std::cout << "\b\b\b\b\b\b\b\b\b\bLoading..." << std::flush;
              Sleep(100);
          }
      }
      

      【讨论】:

        【解决方案5】:

        保持非常简单,您可以使用退格字符 as explained here,它实际上似乎与您的问题重复。 对于更复杂的事情,它会针对特定平台;如果您使用的是 Windows,则可以设置光标位置 this can help

        【讨论】:

          【解决方案6】:

          还有一个跨平台的答案:

          #include <iostream>
          #include <chrono>
          #include <thread>
          
          /* Comment for c++11 solution. */
          using namespace std::literals::chrono_literals;
          
          int main(int argc, char** argv)
          {
              /* Uncomment for c++11 solution. */
              // std::chrono::seconds s(1);
          
              std::cout << '-' << std::flush;
              for (;;) {
                  std::this_thread::sleep_for(1s);
                  std::cout << "\b\\" << std::flush;
                  std::this_thread::sleep_for(1s);
                  std::cout << "\b|" << std::flush;
                  std::this_thread::sleep_for(1s);
                  std::cout << "\b/" << std::flush;
                  std::this_thread::sleep_for(1s);
                  std::cout << "\b-" << std::flush;
              }
          
              return 0;
          }
          

          请注意,chrono_literals 仅在 c++14 中可用,您可以改用std::chrono::seconds s(1);,将s 传递给std::thread::sleep_for();

          【讨论】:

            【解决方案7】:
            for(i=0; i<100; i++)
            {
                system("cls");
                cout << "Loading: " << i << " %  \n";
                if(i==100)
                {    
                    redirect to void or... ?
                }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-06-15
              • 1970-01-01
              • 1970-01-01
              • 2014-04-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多