我正在尝试更改控制台中文本的颜色。
我们应该使用配置文件从以下位置读取ansi转义码:
这就是我文件中的内容
red \033[0;31m #red
blue \033[0;34m #blue
green \033[0;32m #green
grey \033[0;37m #grey
这是我的代码:
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
#include <fstream>
#include <map>
using namespace std;
int main(int argc, char * argv[]){
string file = "config.txt";
string line = "";
string tag = "";
string ansi = "";
map <string, string> m;
if(argc == 2){
file = argv[1];
}
ifstream in(file, ios_base::in | ios_base::binary);
if(!in){
cerr<<"could not open file";
}
while (getline(in, line)){
istringstream iss(line);
if(iss>>tag>>ansi){
auto it = m.find(tag);
if(it == m.end()){
m.insert(make_pair(tag,ansi));
}
}
}
for(auto x: m){
cout<<x.second<<x.first<<endl;
}
cout<<"\033[0;35mhello";
return 0;
}
不确定为什么但只有最后一个打印语句实际显示为彩色,另一个输出ansi转义码作为文本。
这是我的输出:
\033[0;34mblue
\033[0;32mgreen
\033[0;37mgrey
\033[0;31mred
hello (in purple)
答案 0 :(得分:1)
文件中的转义序列不会转换为ESC字符。
此外,您的文件有共同部分。
出于这个原因,我将包含ESC字符的公共部分移动到程序,并使配置文件只有颜色代码。
文件:
#! /usr/bin/awk -f
BEGIN { inmenu = 0 }
/<span class="header">/ {
print "<div class=\"panel panel-default\">"
print "<div class=\"panel-heading\">"
print " <h3 class=\"panel-title\">"
print " <i class=\"fa fa-arrow-left\"></i> " sometextinhere($0)
print " </h3>"
print "</div>"
next
}
/<ul class="menu">/ {
inmenu = 1
print "<div class=\"list-group\">"
next
}
inmenu && /href="anurl\.php"><img src="images\/icons\/todolist\.png"/ {
print " <a href=\"anurl.php\" class=\"list-group-item\">"
print " <i class=\"fa fa-arrow-left fa-fw\"></i> " sometextinhere($0)
print " </a>"
next
}
inmenu && /href="anurl\.php\?action/ {
print " <a href=\"anurl.php\" class=\"list-group-item\">"
print " <i class=\"fa fa-arrow-left fa-fw\"></i> " sometextinhere($0)
print " </a>"
next
}
inmenu && /href="anurl\.php\?action/ {
print " <a href=\"anurl.php\" class=\"list-group-item\">"
print " <i class=\"fa fa-arrow-left fa-fw\"></i> " sometextinhere($0)
print " </a>"
next
}
inmenu && /href="anurl\.php"><img\ src="images\/icons\/domains\.png"/ {
print " <a href=\"anurl.php?action=anaction\" class=\"list-group-item\">"
print " <i class=\"fa fa-arrow-left fa-fw\"></i> " sometextinhere($0)
print " </a>"
next
}
inmenu && /href="#" onClick="showDialog\('(geninvoices|cccapture)'\)/ {
print " <a href=\"#\" onClick=\"showDialog('cccapture');return false\" class=\"list-group-item\">"
print " <i class=\"fa fa-arrow-left fa-fw\"></i> " sometextinhere($0)
print " </a>"
next
}
inmenu && /<\/ul>/ {
print "</div>"
inmenu = 0
next
}
{ print; next }
function sometextinhere(line, r) {
r = line
sub(/.* class="absmiddle" width="16" height="16" \/> /, "", r)
sub(/\<\/a\>\<\/li\>[ \t]*$/, "", r)
return r
}
程序:
red 31 #red
blue 34 #blue
green 32 #green
grey 37 #grey
答案 1 :(得分:1)
读取config.txt文件的问题是读取字符串,就像它被分配为:
std::string str = "\\033[0;31m";
即。 \
被视为一个角色。您在代码中需要的是"\033"
,即由八进制数033
表示的字符。
您可以更改代码中的以下行,以忽略字符串的"\\033"
部分并打印八进制数。
cout << x.second << x.first <<endl;
需要:
cout << '\033' << x.second.substr(4) << x.first <<endl;
通过这项更改,我在桌面上尝试了您的程序,它按预期工作。
答案 2 :(得分:1)
代替这样做:
cout<<"\033[0;35mhello";
C ++提供了编写自己的流操纵器(如std :: endl)以处理转义代码的可能性。
目标是编写这样的代码,这些代码对我来说似乎更具可读性:
cout << ansi::foreground_magenta << "hello" ;
要编写自己的流操纵器,您可以像这样进行操作(简单的原始实现,但是您需要从地图中获取价值...):
#include <ostream>
namespace ansi {
template < class CharT, class Traits >
constexpr
std::basic_ostream< CharT, Traits > & reset( std::basic_ostream< CharT, Traits > &os )
{
return os << "\033[0m";
}
template < class CharT, class Traits >
constexpr
std::basic_ostream< CharT, Traits > & foreground_black( std::basic_ostream< CharT, Traits > &os )
{
return os << "\033[30m";
}
template < class CharT, class Traits >
constexpr
std::basic_ostream< CharT, Traits > & foreground_red( std::basic_ostream< CharT, Traits > &os )
{
return os << "\033[31m";
}
...
} // ansi
或者,C提供了使用#define创建常量的可能性。
#define foreground_magenta "\033[35m"