Sto facendo un progetto scolastico in cui ho bisogno di cambiare frequentemente il colore del testo. Il target del progetto è l'app Console al momento solo per Windows. Utilizzo di Codeblock con MinGW per il debug. Non sono un noob, ma Intermedio-ish.Come posso rendere la mia funzione appiccicosa per gli operatori di estrazione iostream sovraccarichi
Quindi, utilizzando questo ovunque nel codice era brutto:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), __col._colour_code);
Anche se ho avvolto in una funzione, è ancora ingombrante e brutto, perché non è possibile continuare la catena cout. Hai spezzare la catena, come è necessario chiamare il SetColour
in una nuova dichiarazione, ad esempio:
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";
Quello che volevo era una funzionalità simile a quella di setw
, setprecision
, ecc Così ho aperto la iomainp.h
e guardò per alcuni suggerimenti :
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;
}
così ho creato una nuova funzione del mio lavoro in maniera analoga al 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;
}
}
SORPRESA! (per me) funziona !! es .:
cout << setcolour(GRAY) << " ID:[" << setcolour(AQUA) << song.GetID() << setcolour(GRAY) << "]" << " "
<< setcolour(GREEN) << song.GetTitle()
<< setcolour(WHITE) << " by "<< setcolour(BRIGHT) << song.GetArtist() << "\n";
Ma consideriamo l'uscita di questo codice:
std::cout << std::setw(20) << setcolour(AQUA) << "1st time" << "\n";
std::cout << "2nd time" << "\n";
std::cout << "3rd time" << "\n";
noti che setw
non ha attaccato, è stato azzerato nella seconda riga. Come ?? (Il debug non ha mostrato alcuna chiamata in esecuzione per resettarlo.)
Ma il mio stick DID setcolour
per il resto del programma. Perché ?? (Sebbene sia al 100% analogo a setw
).
Come posso fare setcolour
proprio come setw
??? Ho bisogno di questa funzionalità per rendere il mio programma più pulito e logico.
Inoltre ho trovato questo: Which iomanip manipulators are sticky
Ma le risposte ei commenti solo lì solo io confusi. Apperentemente, setw
chiama cout.width (0), ma il debug non ha mostrato tale chiamata, né tale riga di codice è stata trovata in iomanip.h
. Inoltre non ho capito la risposta lì. Spiega per favore.
EDIT
forse non ero diretto nella porre la domanda. Come cout.width(0)
(in un contesto di setw
) viene chiamato ogni volta,
Come posso fare il mio SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0)
(in un contesto di setcolour
) ottenere chiamato ogni volta ??? Come devo affrontare questo problema ??
Che cosa stai usando per visualizzare l'uscita? Un terminale Linux? In tal caso, impostare il colore/carattere è solo una questione di stampare un tag. E il testo dovrebbe mantenere la formattazione finché non si stampa esplicitamente un altro tag. – Rubens
La larghezza per uno stream viene ripristinata dopo ogni scrittura, motivo per cui 'setw' è" antiaderente ". Poiché apparentemente ogni altro iomanip è "appiccicoso", è probabilmente meglio mantenere "setcolour" come è. L'unica altra cosa che posso pensare è scrivere un wrapper per i flussi di output. –
@ AneesAhmed777 Sono solo curioso .. cambia l'ordine di chiamata a 'std :: cout << setcolour (AQUA) << std :: setw (20) <<" 1a volta "<<" \ n ";' causa qualche cambiamento all'output ..? – Minato