2014-09-24 16 views
0

認爲我已經完成並準備好提交這個小項目,直到我找到這個意外的曲線球。 目標是使用令牌詞法分析器來製作解析器。 實質上 <underline><red> R <green> G </green> <blue> B </blue> and back to red </red></underline> 將輸出爲:「RGB和回到紅色」在他們各自的顏色和屬性。使用cout << term_cc <color,default,attrib>在Windows終端上輸出顏色和屬性的C++輸出到Windows終端上,但不是在Linux上正確輸出顏色和屬性

一切正常工作在Windows上,但當我把它移到Linux系統它輸出的顏色代碼沒有任何事情發生。

#include <iostream> 
#include <sstream> 
#include <stack> 
#include <map> 
#include <cstdlib> 
#include <vector> 
#include "cmd.h" 
#include "Lexer.h" // you should make use of the provided Lexer 
#include "term_control.h" 
#include "error_handling.h" 

using namespace std; 

map<string, term_colors_t> colorMap;  
map<string, term_attrib_t> attribMap; 
string display(const string& expression) 
{ 
if(validate(expression) == "VALID") { 
Lexer lex; 
Token tok; 

vector<term_colors_t> colorVect; 
vector<term_attrib_t> attribVect; 

lex.set_input(expression); 
while(lex.has_more_token()){ 
    tok = lex.next_token(); 
    string sTok = tok.value; 
     if(tok.type == TAG && tok.value.at(0) != '/'){ 
      cout<<term_cc(colorMap[tok.value], DEFAULT_COLOR, attribMap[tok.value]); 
      colorVect.push_back(colorMap[tok.value]); 
      attribVect.push_back(attribMap[tok.value]); 
     } 
     if(tok.type == TAG && tok.value.at(0) == '/'){ 
     colorVect.pop_back(); 
     cout<<term_cc(colorVect.back(), DEFAULT_COLOR, attribVect.back()); 
     } 
     if(tok.type != TAG){ 
      cout<<tok.value; 
     } 
    } 
} 
else if(validate(expression) != "VALID") return validate(expression); 
return ""; 

}

_

cout<term_cc(Color, DEFAULT_COLOR, Attribute) 

是specfic方法,其中的問題是躲在我一直在尋找周圍,似乎無法找到正確的方法。

cout<<term_fg(color) 

該方法在Linux系統上正確顯示顏色,但我不能使用該方法的屬性。

我一直在閱讀的一切都只涉及顏色而不是顏色和屬性,他們也使用echo命令和特定終端的硬編碼顏色。這些都需要對我的所有代碼進行重大更改,並導致它無法在Windows上運行,只能在Linux上運行,所以我試圖避免這種情況。

在此先感謝有關此問題的任何建議,我希望每個人都能夠在12之前得到這個結果!

+0

什麼是'term_cc'或'term_fg'?你在用圖書館嗎?如果是這樣,它應該在問題或標籤中提及。 – 2014-09-24 01:38:08

+0

您是否在您提供的代碼中表示cout 2014-09-24 01:41:23

+0

添加了一切抱歉的混蛋傢伙。 和cout << term_cc @MichaelPetch – Michael 2014-09-24 01:54:41

回答

1

這不是很清楚,我在那裏colorMapattribMap被初始化到什麼價值觀,我只是本能這裏,但它很可能是爲attribMapcolorMap是顏色的鍵和鍵屬性。在這種情況下,underline不是colorMap中的密鑰,red不是attribMap中的密鑰。

在你的程序,請執行以下操作:

if(tok.type == TAG && tok.value.at(0) != '/'){ 
     cout<<term_cc(colorMap[tok.value], DEFAULT_COLOR, attribMap[tok.value]); 

它假定每個TAG是存在於colorMapattribMap。但是,如果標籤的顏色類似於"red",則它(可能)僅在colorMap中,並且如果它是"underline"之類的屬性,則(可能)僅在attribMap中。

現在,執行colorMap["underline"]會發生什麼?在這裏,C++標準庫的便利性可能有點不利,因爲它默默地隱藏了一個錯誤。答案是從映射"underline"到默認值term_colors_t的映射將被添加到映射,以便查找將始終返回一些內容。 term_colors_t是一個枚舉,因此其默認值爲0而不是'0')。

現在,term_cc - 如果是相同的term_cc @MikePetch挖出來 - 不檢查它的參數的有效性;它只是假定它們是有效的ANSI數字('0''9',或者換句話說是48和57之間的數字,包括端點在內。)由於它不檢查它們,它只是輸出包含它們,因爲它們在它的輸出中,並且由於您(可能)調用term_cc的屬性參數爲0 - 即NUL字符 - 它輸出NUL作爲假設控制檯代碼的一部分。

我檢查了xterm,konsole和Linux控制檯,它們都忽略了NUL這個字符。 (我相信這是預期的行爲;像VT-100這樣的DEC終端忽略了NUL s,儘管在某些情況下你需要插入它們,因爲如果以前的控制時間太長,終端也會忽略任何字符)。我沒有知道您正在使用哪種終端仿真器,並且很可能它具有不同的行爲,例如終止控制代碼序列。 term_cc首先輸出屬性,即使它是第三個參數,所以很可能是因爲NUL屬性會導致終端仿真器僅打印類似;31;49m的東西,而不是將前景色設置爲紅色。

一些其他錯誤:

  • 你永遠不彈出attribVect;只有colorVect。所以我不明白這些屬性如何正確恢復。

  • 您不會將colorVect初始化爲DEFAULT_COLOR。因此,彈出第一個標記後,您將彈出colorVect(僅)元素,將其留空,然後調用colorVect.back(),如果colorVect爲空,則該元素未定義。

這些只是我注意到通過代碼快速瀏覽的東西。可能還有其他問題。

+1

即使在Windows上,我也無法正確地看到*實際正常工作。它可能會運行,但我懷疑你正在得到預期的結果。 – 2014-09-24 06:11:18