我正在做一个需要经常更改文本颜色的学校项目。项目目标是当前仅适用于 Windows 的控制台应用程序。使用带有 MinGW 的代码块进行调试。我不是菜鸟,而是中级。
所以在代码中到处使用它是丑陋的:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), __col._colour_code);
即使我将它包装在一个函数中,它仍然很麻烦和丑陋,因为你不能继续你的 cout 链。你已经打破了链条,因为你必须SetColour
在一个新的语句中调用,例如:
SetColour(GRAY); cout << setcol(PURPLE) << " ID:[";
SetColour(AQUA); cout << song.GetID();
SetColour(GRAY); cout << "]" << " ";
SetColour(GREEN); cout << song.GetTitle();
SetColour(WHITE); cout << " by ";
SetColour(BRIGHT); cout << song.GetArtist() << "\n";
我想要的是类似 , 等的功能setw
。setprecision
所以我打开iomainp.h
并寻找一些提示:
struct _Setw { int _M_n; };
inline _Setw
setw(int __n)
{ return { __n }; }
template<typename _CharT, typename _Traits>
inline basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, _Setw __f)
{
__is.width(__f._M_n);
return __is;
}
template<typename _CharT, typename _Traits>
inline basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, _Setw __f)
{
__os.width(__f._M_n);
return __os;
}
因此,我以 100% 类似的方式创建了自己的新功能:
enum Colour { BLACK=0x00, DARK_GREEN=0x02, WHITE=0x07, GRAY,
BLUE=0x09, GREEN, AQUA, RED, PURPLE, YELLOW, BRIGHT };
struct _colour_struct
{
uint8_t _colour_code;
};
inline _colour_struct setcolour (Colour colour_foregrnd, Colour colour_backgrnd =BLACK)
{
uint8_t colour_code = colour_backgrnd;
colour_code <<= 4;
colour_code |= colour_foregrnd;
return { colour_code };
}
namespace std
{
template<typename _CharT, typename _Traits>
inline basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, _colour_struct __col)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), __col._colour_code);
return __os;
}
}
惊喜!(对我来说)它的工作!例如:
cout << setcolour(GRAY) << " ID:[" << setcolour(AQUA) << song.GetID() << setcolour(GRAY) << "]" << " "
<< setcolour(GREEN) << song.GetTitle()
<< setcolour(WHITE) << " by "<< setcolour(BRIGHT) << song.GetArtist() << "\n";
但考虑一下这段代码的输出:
std::cout << std::setw(20) << setcolour(AQUA) << "1st time" << "\n";
std::cout << "2nd time" << "\n";
std::cout << "3rd time" << "\n";
请注意,setw
没有粘住,它是在第二行重置。如何 ??(调试显示没有执行额外的调用来重置它。)
但是我的setcolour
DID 坚持了程序的其余部分。为什么 ??(尽管它 100% 类似于setw
)。
我怎么能setcolour
像setw
???我需要这个功能来使我的程序更干净和合乎逻辑。
我还发现了这个: 哪些 iomanip 操纵器很粘
但是那里的答案和评论只会让我感到困惑。显然,setw
调用 cout.width(0),但调试显示没有这样的调用,也没有在iomanip.h
. 也不明白那里的答案。请解释。
编辑
也许我没有直接问这个问题。就像cout.width(0)
(在上下文中setw
)每次都被调用,
我怎样才能让我的SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0)
(在上下文中setcolour
)每次都被调用???
我应该如何解决这个问题?