我一直在做很多阅读,并且在C ++中没有找到任何良好的控制台输出格式。我正在打印一个带有循环的三角形,我知道如何打印它,但我想在控制台中移动它,所以我可以在cathetus旁边有文字。
所以我希望我的输出像
*
* *
8.5 inches * *
* *
*********
这是绘制三角形的函数:
void Triangle::DisplayTriangle() {
for (int x = 0; x <= 10; x++) {
setprecision(2);
for (int j = x; j > 10; j++) cout << " ";
for (int z = 0; z <= x; z++) {
if (x == 10) {
cout << '*';
}
else if (z == 0 || z == x) cout << "*";
else cout << " ";
}
for (int y = 0; y < x; y++) {
cout << " ";
}
cout << endl;
}
}
答案 0 :(得分:1)
当目标输出变得更复杂时,手动循环绘制形状会变得非常困难。
所以在某些时候,你会想要使用一个文本绘图库(比如K. Shores提到的ncurses)。
然而,滚动你自己的简单绘图API不是脑部手术:
#include <iostream>
namespace auto_list_exploit {
static auto li = {1,2};
using initializer_list = decltype(li);
}
template <typename CT=char>
class TextSurface {
using initializer_list = auto_list_exploit::initializer_list;
public:
struct point {
int x,y;
point(int x=0, int y=0) : x(x), y(y) {}
point(initializer_list list) : x((list.begin())[0]), y((list.begin())[1]) {}
};
private:
int m_width, m_height, m_data_count;
CT* m_data;
int OffsetOf(int x, int y) const { return y * m_width + x; }
bool IsInside(int x, int y) { return x >= 0 && y>= 0 && x < m_width && y < m_height; }
CT& at(int x, int y) { return m_data[OffsetOf(x,y)]; }
CT at(int x, int y) const { return m_data[OffsetOf(x,y)]; }
int Abs(int x) { return x < 0 ? -x : x; }
void Poly(const point& pfirst, CT value, const point& plast) {
Line(plast, pfirst, value);
}
template <typename ...Ts>
void Poly(const point& pfirst, CT value, const point& p0, const point& p1, Ts...args) {
Line(p0, p1, value);
Poly(pfirst, value, p1, args...);
}
public:
TextSurface(int width=0, int height=0) :
m_width(height ? width : 0),
m_height(width ? height : 0),
m_data_count(width * height)
{
m_data = m_data_count ? new CT[m_data_count] : nullptr;
Clear();
}
// Cannot copy
TextSurface(const TextSurface&) =delete;
TextSurface& operator = (const TextSurface&) =delete;
// Can return from functions
TextSurface& operator = (TextSurface&& src) {
delete [] m_data;
m_width = src.m_width; m_height = src.m_height; m_data_count = src.m_data_count;
m_data = src.m_data;
src.m_data = nullptr;
return *this;
}
TextSurface(TextSurface&& src) : m_data(nullptr) { operator = ((TextSurface&&)src); }
~TextSurface() { delete [] m_data; }
int Width() const { return m_width; }
int Height() const { return m_height; }
void Clear(CT value=' ') {
CT* p = m_data;
CT* pe = p + m_data_count;
while(p != pe) *(p++) = value;
}
void Line(int x0, int y0, int x1, int y1, CT value) {
const int dx = x1-x0;
const int dy = y1-y0;
if(!dx && !dy) {
if(IsInside(x0, y0)) { at(x0, y0) = value; }
return;
}
const bool ymajor = Abs(dy) > Abs(dx);
int x=x0, y=y0;
int &mj = ymajor ? y : x;
int &mn = ymajor ? x : y;
const int mje = ymajor ? y1 : x1;
const int mjst = mj < mje ? 1 : -1;
double mnd = mn;
double mnst = ymajor ? double(dx)/Abs(dy) : double(dy)/Abs(dx);
do {
mn = int(mnd + 0.5);
if(IsInside(x,y)) { at(x,y) = value; }
mj += mjst;
mnd += mnst;
} while(mj != mje+mjst);
}
void Line(const point& p0, const point& p1, CT value) { Line(p0.x, p0.y, p1.x, p1.y, value); }
template <typename ...Ts>
void Poly(CT value, const point& p0, const point& p1, Ts...args) {
Line(p0, p1, value);
Poly(p0, value, p1, args...);
}
// init-list overloads for triangle and quad (initializer_list can't be packed)
void Poly(CT value, initializer_list l0, initializer_list l1, initializer_list l2) { Poly(value, point(l0), point(l1), point(l2)); }
void Poly(CT value, initializer_list l0, initializer_list l1, initializer_list l2, initializer_list l3) { Poly(value, point(l0), point(l1), point(l2), point(l3)); }
void Rect(int x, int y, int width, int height, CT value) {
Poly(value, point(x,y), point(x+width-1, y), point(x+width-1, y+height-1), point(x, y+height-1));
}
// Label places text. xloc selects the meaning of the x coordinate.
// Its value is between -1 and 1: -1 for x at the left of the text,
// 0 for x in the middle, and 1 for x at the end of the text.
void Label(const CT* text, int x, int y, double xloc=-1) {
int len = 0;
while(text[len]) { ++len; }
x -= int((xloc + 1)/2 * (len - 1));
for(int i=0; i<len; ++i) {
if(IsInside(x,y)) { at(x,y) = text[i]; }
++x;
} }
void Present() const {
const CT* p = m_data;
for(int j=0; j<m_height; ++j) {
std::cout.write(p, m_width);
std::cout << '\n';
p += m_width;
} }
};
typedef TextSurface<char> CharSurface;
int main() {
CharSurface surf(60,20);
surf.Poly('*', {20,2}, {34,16}, {20,16});
surf.Label("14 ft", 18, 10, 1);
surf.Label("9 ft", 26, 17, 0);
surf.Present();
}
main()
输出中的示例:
*
**
* *
* *
* *
* *
* *
* *
14 ft * *
* *
* *
* *
* *
* *
***************
9 ft