我正在尝试创建旋转光标动画的事情。
每次编译的时候,我总是在最后留下一个(或两个)斜线,而且退格字符也不起作用。我用了两种方法:睡眠功能和计时功能,它们的工作原理非常相似,在旋转后留下一个斜线,忽略了退格字符。
如果我省略任何换行字符或操作符,这个工作方式和预期不同。
void spinningCursor() {
for (int i = 1; i <= 100; ++i)
{
cout << "-" << flush;
this_thread::sleep_for(chrono::milliseconds(10));
cout << "\b" << flush;
cout << "\\" << flush;
this_thread::sleep_for(chrono::milliseconds(10));
cout << "\b" << flush;
cout << "|" << flush;
this_thread::sleep_for(chrono::milliseconds(10));
cout << "\b" << flush;
cout << "/" << flush;
this_thread::sleep_for(chrono::milliseconds(10));
cout << "\b" << flush;
}
}
或者...
void spinningCursor2() {
for (int i = 0; i < 100; i++) {
cout << "-";
cout.flush();
usleep(10000);
cout << "\b";
cout.flush();
cout << "\\";
cout.flush();
usleep(10000);
cout << "\b";
cout.flush();
cout << "|";
cout.flush();
usleep(10000);
cout << "\b";
cout.flush();
cout << "/";
cout.flush();
usleep(10000);
cout << "\b";
cout.flush();
}
}
主要功能...
int main()
{
spinningCursor();
cout <<"\nHello, World!"<< endl;
spinningCursor2();
cout <<"\nHello, World, Again!"<< endl;
return 0;
}
虽然不能保证输出效果,但把它分成几段可能会有帮助。
想法。
#include <algorithm>
#include <chrono>
#include <cstddef>
#include <iostream>
#include <string>
#include <thread>
using namespace std::chrono_literals; // a cumbersome way to be able to write 100ms
// unformatted output of one char, a backspace, flushing and Zzz...
void slow_put(char ch) {
static const auto delay = 100ms;
static const char bs = '\b';
std::cout.write(&ch, 1);
std::cout.write(&bs, 1);
std::cout.flush();
std::this_thread::sleep_for(delay);
}
// newline, but erase the char under it first
void nl() {
std::cout.write(" \n", 2);
}
// proxy ... decorate stuff here (for debugging etc)
void display(char ch) {
slow_put(ch);
}
// enabler to repeat a bunch of sequences
void spinner(const std::string& sequence) {
// execute the display function for one char at a time
std::for_each(sequence.begin(), sequence.end(), display);
}
// example use of the helpers above
void spinningCursorSchema(size_t times) {
static const std::string seq = R"raw(|/-\)raw"; // the pattern to display
while(times--) spinner(seq);
// add more patterns to this schema if wanted
}
int main() {
std::cout << "Spinner: [ ]\b\b";
spinningCursorSchema(100); // run the spinningCursor 100 times
nl(); // erasing newline
}
编辑:简单解释一下。对于你调用的每一组函数,我 毛毡 可以命名为,"do_this()
"或"do_that()
" 我把它们放在一个函数中,并给它们起了相应的名字。
这个练习的目的主要不是让我找到你代码中的错误,而是提供一个参考框架。当一个人可以说 "你的... "的时候,就更容易发现问题并进行修复。do_this()
功能需要 这个 或 该... "或类似的。当所有的东西都在一个大的代码块中时,每个人阅读它都需要从零开始。一个有明确名称的函数(或者像我上面做的那样用注释来弥补糟糕的命名,"proxy")和只有几行代码的函数可以被每个人审查,而不需要对更大的问题有太多的背景知识。
简而言之,我把你那段专门为做一件事而创建的代码分解成了几个函数,我用这些函数重建了类似于你最初想法的东西。通过这样做,我更容易看到缺陷,谈论设计决策。如果一个2-4行的函数可以被10000人审查,而他们没有发现问题,那么这个函数是问题(本身)的可能性很小。通过构建具有明确目的的小函数块,bghunting变得对每个人来说都更可用,而不仅仅是深深卷入你要解决的特定问题的人。
我现在看到,我使用了一个函数模板,从 <algorithm>
可能不熟悉的。std::for_each
. 在这种情况下,它可以被替换为。
for(char ch : sequence) display(ch);
仔细想想,那就更清楚了。 Come to think of it, that's even clearer.
如果这不是你想要的概述,请评论并指出你希望得到解释的部分,我将再次尝试。