c ++ ansi转义代码不向控制台显示颜色

时间:2015-10-25 03:57:21

标签: c++ ansi

我正在尝试更改控制台中文本的颜色。

我们应该使用配置文件从以下位置读取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)

3 个答案:

答案 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>&nbsp; " 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>&nbsp; " 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>&nbsp; " 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>&nbsp; " 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>&nbsp; " 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>&nbsp; " 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"