Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Due to spam on this forum, all posts now need moderator approval.
Entire forum
➜ SMAUG
➜ SMAUG coding
➜ Colour tokens causing misalignment with string formatting (e.g. %-40s)
Colour tokens causing misalignment with string formatting (e.g. %-40s)
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
Posted by
| Marowi
(65 posts) Bio
|
Date
| Sun 13 Jul 2014 02:12 AM (UTC) |
Message
| Hey folks,
I've been digging into a problem with aligning coloured text, and am running short on ideas. I'm working with a modified SMAUG/SWR codebase, but I believe this is primarily related to standard functions.
The problem : using '%-40s' (or any string format/length token) will consider the colour tokens as part of the '40', and the output will consequently be 2 shorter than I want.
The code:
ch_printf( ch, "&zName: &c%-40s &zVnum: &c%d\n\r", (location->name), location->vnum );
ch_printf( ch, "&zName: &c%-40s &zVnum: &c%d\n\r", showclr(location->name), location->vnum );
ch_printf( ch, "&zName: &c%-40s &zVnum: &c%d\n\r", stripclr(location->name), location->vnum );
ch_printf( ch, "&zName: &c%-40s | strlen: %d | strlen_color: %d\n\r", location->name, strlen(location->name), strlen_color(location->name));
The output:
Name: The Kuragame Waterfall Vnum: 4102
Name: &pThe Kuragame Waterfall Vnum: 4102
Name: The Kuragame Waterfall Vnum: 4102
Name: The Kuragame Waterfall | strlen: 24 | strlen_colour: 22
Technically, there are 24 characters in the string provided, so it's not entirely incorrect to be adding only 16 spaces to make it to the 40 requested. However, I would like it to disregard the colour tags when counting characters.
My best guess is that it's because ch_printf() has no idea that I'm going to swap colour tokens for ANSI code, so when it calculates string length, it's doing the best it can without that information.
ch_printf:
void ch_printf( CHAR_DATA *ch, char *fmt, ... )
{
char buf[MAX_STRING_LENGTH*2];
va_list args;
va_start( args, fmt );
vsnprintf( buf, MAX_STRING_LENGTH*2, fmt, args );
va_end( args );
send_to_char_color( buf, ch );
}
I'm at a bit of a loss as to how other MUDs handle this; perhaps I should have opened with the question - do they?
Any advice is appreciated!
-Marowi | Top |
|
Posted by
| Meerclar
USA (733 posts) Bio
|
Date
| Reply #1 on Sun 13 Jul 2014 06:05 AM (UTC) |
Message
| Honestly, every mud I've worked on has resorted to either coding in the colors elsewhere, adding in extra whitespace to account for the color codes in that string or saying screw it and still does it oldschool. There's also the option of checking the string and subtracting 2 from strlen for every color code in the provided text. Of more concern to me though is the fact that your sample text offsets aren't correct.
2nd should be offset 2 from the first and isn't after the whitespace. |
Meerclar - Lord of Cats
Coder, Builder, and Tormenter of Mortals
Stormbringer: Rebirth
storm-bringer.org:4500
www.storm-bringer.org | Top |
|
Posted by
| Marowi
(65 posts) Bio
|
Date
| Reply #2 on Sun 13 Jul 2014 05:17 PM (UTC) |
Message
| Trying to determine in which cases to add the whitespace is the difficult part. I'd only want it for particular strings, where the formatting means misalignment (who list, etc).
I have a strlen_color function that doesn't count the colour codes, but it seems that the string length is already determined before it gets to any sort of color conversion code.
The sample text offsets are correct. With this codebase, 'showclr' doubles up any colour codes in the string, so they display in the output.
e.g. "&BOcean" + showclr = "&&BOcean"
I guess I could not bother with alignment for any strings that could have colours, and strip out the colours for any strings I definitely want aligned.
Thanks for your reply. | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #3 on Sun 13 Jul 2014 08:44 PM (UTC) |
Message
| In the source (color.c) I found this, doesn't that do what you want?
/*
* Quixadhal - I rewrote this too, so that it uses colorcode. It may not
* be as efficient as just walking over the string and counting, but it
* keeps us from duplicating the code several times.
*
* This function returns the intended screen length of a string which has
* color codes embedded in it. It does this by stripping the codes out
* entirely (A NULL descriptor means ANSI will be FALSE).
*/
int color_strlen( const char *src )
...
Using that you can find the length of the string without colour codes, then just work out how many spaces to send afterwards. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Marowi
(65 posts) Bio
|
Date
| Reply #4 on Sun 13 Jul 2014 10:22 PM (UTC) |
Message
| I wrote a strlen_color, which presumably does the same thing. In the example, strlen(location->name) returns 24, while strlen_color(location->name) returns 22.
The problem I'm having is that the %-40s has no concept of anything except the raw text passed to it, which it correctly determines as 24 characters in length, and adds another 16 spaces.
Your suggestion did give me the idea that I add another %s after the %-40s, and instead count the colour codes inside (location->name) and add that many spaces - it's messy, but if absolutely necessary, it could work. | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #5 on Mon 14 Jul 2014 09:10 AM (UTC) |
Message
| Yes that was what I meant. In fact you can probably print "" (an empty string) with a dynamic length, eg.
Then supply the number of spaces you want as an integer before the blank string (or is it after?) Like that, anyway. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Marowi
(65 posts) Bio
|
Date
| Reply #6 on Thu 17 Jul 2014 06:33 AM (UTC) |
Message
| Ah! Fantastic. I hadn't known it was possible to insert a dynamic length token like that; a quick search revealed that a lot of people have the same reaction.
Thanks again for all the responses - got this sorted for now! | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
20,666 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top