Jump to content

  • Log In with Google      Sign In   
  • Create Account


Custom cout formatting using /tags


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 chondee   Members   -  Reputation: 135

Like
0Likes
Like

Posted 09 May 2012 - 01:41 AM

Hi,

In my game engine I output stuff for debugging purposes to the windows console using std::cout.
I wanted to use colors so I can more easily oversee what is going on, as well as some "macros" using /tags.
Let me show an example of what I am talking about:

myCout << "/warn Entity: "<< EntityName << "is doing /fgRed badstuff \n";

would output:

Warning: Entity: obj1 is doing badstuff


The way I have this is that I parse a stringstream.str() and send that string to my function that will format it and output it, but it currently looks like:

mysstream << "/warn Entity: "<< EntityName << "is doing /fgRed badstuff \n";
myCout(mysstream.str());

Obviously, I don't want to do this for every output, I want to use my output function just like std::cout, having the functionality of the same << operators, but does my formatting also.

How could I achieve this?
Your help is much appreciated!

Sponsor:

#2 doeme   Members   -  Reputation: 700

Like
1Likes
Like

Posted 09 May 2012 - 03:49 AM

In the end you have to parse your string somewhere if you want to work with tags like this. Another way would be that your format your streams like the C++ streams with flags that can be passed to the stream instead of stringbased tags. (Google "C++ stream formatting" for this), which might mean that you have to create your own stream implentation and maybe a custom "device" or widget to display your messages.

Another simple way would be to define different macros which encapsulate your stream. But the problem with changing colors inside the message remains.
#define Info std::cout << "INFO: "
#define Warn std::cout << "WARNING: "
...
Info << "some information message\n";
Warn << "Warning stuff and a float: " << 1.0f << "\n";


#3 mrjones   Members   -  Reputation: 612

Like
0Likes
Like

Posted 09 May 2012 - 04:03 AM

I'd do something like this:

#include <iostream>
#include <windows.h>

using namespace std;

struct color {
    unsigned char c;
    color(unsigned char _c=0) : c(_c) {}
};
const color black(0);
const color blue(1);
const color green(2);
const color aqua(3);
const color red(4);
const color purple(5);
const color yellow(6);
const color white(7);
const color gray(8);
const color lightblue(9);
const color lightgreen(10);
const color lightaqua(11);
const color lightred(12);
const color lightpurple(13);
const color lightyellow(14);
const color brightwhite(15);

// Overload stream operator with color
std::ostream& operator<<(std::ostream& str, const color& c);

HANDLE handle;            ///< Output handle

int main() {
    if(AllocConsole());
    handle=GetStdHandle(STD_OUTPUT_HANDLE);

    cout << lightgreen << "Hello world!" << white << endl;
}

void setColor(unsigned char color) {
    if(handle)    SetConsoleTextAttribute(handle, color);
}

std::ostream& operator<<(std::ostream& str, const color& c) {
    setColor(c.c);
    return str;
}


#4 chondee   Members   -  Reputation: 135

Like
0Likes
Like

Posted 09 May 2012 - 04:11 AM

Thanks for your replies doeme and mrjones!

The reason I would like it string based, that in that way I could also parse text from files that will be formatted and colored the way I want.

The reason I don't want to use hardcoded macros is because I would like my engine to be able to handle per-project custom tags, such that a file can be parsed that describes a list of custom tags and their corresponding custom strings (defined by the user without knowledge or access to engine code) that they resolve into and will be placed in a std::map<string, string>
example : "/goblin" = "/fgCyan GoblinName: /fgDarkGreen /bgWhite"

Any ideas?
Or is this impossible with a one liner? (like a cout statement?)

Edited by chondee, 09 May 2012 - 04:13 AM.


#5 chondee   Members   -  Reputation: 135

Like
0Likes
Like

Posted 09 May 2012 - 04:17 AM

I guess it comes down to this:

Do I have to sacrifice one of the following:
1. String based color tags and macros
2. <<Operator for string conversion of variables

for this to be possible in a one line statement?

Edit:
If yes, than for THAT I could actually use a macro that aggregates the stringstream statement and the myFormattingCout(stringstream.str())

If it is however possible without a macro I would rather take that, so please let me know if you think it is.

Edited by chondee, 09 May 2012 - 04:19 AM.


#6 mrjones   Members   -  Reputation: 612

Like
1Likes
Like

Posted 09 May 2012 - 04:28 AM

Anything is possible. Maybe something like this would work for you? Example is without formatting and without colors output.

std::ostream& operator<<(std::ostream& str, const char* c);

int main() {
    if(AllocConsole());
    handle=GetStdHandle(STD_OUTPUT_HANDLE);

    cout << "/fgCyan" << endl;
}

void setColor(unsigned char color) {
    if(handle)    SetConsoleTextAttribute(handle, color);
}

std::ostream& operator<<(std::ostream& str, const char* c) {
    setColor(lightblue.c);

    // Do formatting and output text in your own colors
    str.write(c, strlen(c));
    return str;
}


#7 chondee   Members   -  Reputation: 135

Like
0Likes
Like

Posted 09 May 2012 - 04:41 AM

Thanks for your help, I'll try your example, my uncertainty in this topic is because I didn't work with custom << operator before.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS