C++控制台打印在同一行上,带回车符

C++ Console print on same line with carriage return

本文关键字:一行 回车 打印 控制台 C++      更新时间:2023-10-16

我有一个控制台应用程序,我想用它来打印进度。但是,为了使它尽可能好,我想打印带有回车符的百分比更新,以保持百分比更新,而不是添加具有新进度状态的新行。

使用回车符打印效果很好,直到我得到一个超出控制台窗口宽度的字符串。显然,回车不会返回到比控制台窗口更长的字符串的开头。

是否有可能捕获此事件并以某种方式再次从字符串的开头开始?

可视化问题:

string = "This is a test string which is longer than the console";
|<-      Console width       ->|
|This is a test string which is|
->| longer than the console      |

回车符使字符串从->开始打印,如上所示

问题是控制台窗口不同。 在 Windows 平台上,您可以调整控制台的宽度和高度。

你可以找到一些 API 来返回控制台窗口的高度和宽度;但不需要平台来支持这一点。

有一些库可以帮助光标定位。 搜索软件推荐(在StackExchange(以查看他们的推荐内容,或在互联网上搜索"C ++光标位置库"。

在Linux上,你在寻找这样的东西吗?

#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
struct winsize size;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &size);
printf ("%dn", size.ws_row);
printf ("%dn", size.ws_col);
}

直到我得到一个超过控制台窗口宽度的字符串。

可以在 c++ 中创建一个小的 util 函数来获取 ncurses 报告的当前屏幕尺寸。

如果在每次输出之前运行它,您将拥有根据字符串大小预测"环绕"所需的维度,并采取所需的操作。 使用字符串流可能非常有用。

#include <iostream>
#include <iomanip>
#include <vector>
// I prefer to not include ncurses here, see below 

// determine current console dimensions
class ConsoleDimensions
{
public:
ConsoleDimensions()  = default;
~ConsoleDimensions() = default;
//
std::string operator()();
};

class T504_t // or any class name you want
{
public:
T504_t() = default;
~T504_t() = default;
int exec()
{
std::cout << "nn" << ConsoleDimensions()() << std::endl;
//                    invokes operator()--^^
return(0);
}
}; // class T504_t

int main(int argc, char* argv[])
{
std::cout << "nargc: " << argc << std::endl;
for (int i = 0; i < argc; i += 1) std::cout << argv[i] << " ";
std::cout << std::endl;
int retVal = -1;
{
T504_t   t504;
retVal = t504.exec();
}
std::cout << "nn  <<< If your C++ 'Hello World' has no class ... "
<<" why bother? >>> nn"
<< std::endl;
return(retVal);
}

// separate this implementation file (.cc)
//     to prevent the curses macros from polluting your non-curses code
#include "cursesw.h"
std::string ConsoleDimensions::operator()()
{
(void)initscr(); // start curses mode
cbreak();
noecho();
// erase()
// refresh()
raw();
// nonl();
// intrFlush(stdscr, FALSE)
keypad(stdscr, true);
// curses uses int (will there ever be a negative height or width?)
int curses_reported_height = 0;
int curses_reported_width  = 0;
getmaxyx(stdscr, curses_reported_height, curses_reported_width);
std::stringstream ss;
ss << "  max y: " << curses_reported_height
<< "  max x: " << curses_reported_width;
endwin();
return(ss.str());
}

在具有默认字体的全屏标准侏儒终端上运行时输出:

max y: 70  max x: 266

你可能只想要数字,而不是文本。 很容易改变

std::string ConsoleDimensions::operator()();

我会考虑,

void ConsoleDimensions::operator()(int& maxY, int& maxX);

具有适当的实现更改。


更新 2017-07-22

使用 std::chrono::high_resolution_clock 进行性能估算,并形成 "void ConsoleDimensions::operator(((int& maxY, int^ maxX(;"

171.2830000 k ConsoleDimension()(int&, int&) events in 4,000,006 us
42.82068577 k ConsoleDimension()(int&, int&) events per second
23.35319909 µ sec per  ConsoleDimension()(int&, int&) event 
dimensions [50,100]

您的结果会有所不同。