Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Quick question on newlines..

This thread is locked; no one can reply to it. rss feed Print
 1   2 
Quick question on newlines..
Neil Black
Member #7,867
October 2006
avatar

Yeah, I know it isn't that hard to do. But when I was first starting out I had no idea how to do it.

OICW
Member #4,069
November 2003
avatar

Reminds me of myself five years ago (that's approximately how that thread is old).

[My website][CppReference][Pixelate][Allegators worldwide][Who's online]
"Final Fantasy XIV, I feel that anything I could say will be repeating myself, so I'm just gonna express my feelings with a strangled noise from the back of my throat. Graaarghhhh..." - Yahtzee
"Uhm... this is a.cc. Did you honestly think this thread WOULDN'T be derailed and ruined?" - BAF
"You can discuss it, you can dislike it, you can disagree with it, but that's all what you can do with it"

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I have a question about the modified version of Kitty Cat's multi line text output. Specifically the line :

           *(next++) = '\n';

From :

1void my_textout1(const char *str, int x, int y)
2{
3 char *str_copy = strdup(str);
4 char *cur, *next;
5 
6 cur = str_copy;
7 while(cur)
8 {
9 next = strchr(cur, '\n');
10 if (next)
11 {
12 *next = 0;
13 *(next++) = '\n';
14 }
15 cur = next;
16 }
17 
18 free(str_copy);
19}

Since a copy is being worked on , the newline doesn't need to be replaced , just setting the address to the next character should suffice. What I don't understand is why the character after the detected newline should be set to a newline? Isn't "*(next++)" the same as "*(next + 1)"? Since 'cur' gets set to the character position right after where the newline is detected and that character position's value has been set to a newline , why doesn't strchr(cur , '\n') keep returning the same value as 'cur'?

In any case , I came up with another version , based on Kitty Cat's as well :

1 
2void multiline_textout_v1(BITMAP* bmp , FONT *font , const char *ml_str , int x , int y , int v_spacing , int fg , int bg) {
3 // note that this will only output the text lines of ml_str if each one ends with a newline '\n' character
4 // so "Line 1\nLine 2\n" would work , but not "Line 1\nLine 2"
5 // And so a normal string would not work either - ("Line 1") would fail
6 // due to the lack of a newline character
7 char* copy = strdup(ml_str);
8
9 char* line = copy;
10 char* endline = strchr(line , '\n');
11
12 while(endline) {
13 *endline = '\0';
14 textout_ex(bmp , font , line , x , y , fg , bg);
15 endline = strchr(line , '\n');
16 line = endline + 1;
17 y += v_spacing;
18 }
19
20 free(copy);
21}

Mark Oates
Member #1,146
March 2001
avatar

Openlayer's TextRenderer does newlines automatically. 8-)

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

Since a copy is being worked on , the newline doesn't need to be replaced , just setting the address to the next character should suffice.

Correct. A mistake on my part.. :P

Quote:

What I don't understand is why the character after the detected newline should be set to a newline? Isn't "*(next++)" the same as "*(next + 1)"?

No. next++ post-increments the 'next' variable. It increments the variable, but "returns" the original value. ++next would increment the variable and give the new value.

A fixed version of my code would be:

1void my_textout(BITMAP *bmp, FONT *f, const char *str, int x, int y, int fg, int bg)
2{
3 char *str_copy = strdup(str);
4 char *cur, *next;
5 
6 cur = str_copy;
7 while(cur)
8 {
9 next = strchr(cur, '\n');
10 if(next) *(next++) = 0;
11 textout_ex(bmp, f, cur, x, y, fg, bg);
12 y += text_height(f);
13 cur = next;
14 }
15 
16 free(str_copy);
17}

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Quote:

No. next++ post-increments the 'next' variable. It increments the variable, but "returns" the original value. ++next would increment the variable and give the new value.

Weird. Not what I would expect to happen given that it's in parentheses. I never thought of post-incrementation as returning the original value.

Had to fix a bug in the version I put up and I also added in a function pointer parameter for which text function gets called. So now you can call textout_ex , textout_centre_ex , or textout_right_ex as an input parameter. My version now also displays the trailing end of the string containing newlines so you don't have to end it with a newline character. Use the v_spacing parameter to control the vertical spacing , and enter one of the three aforementioned allegro text functions for the text_func parameter.

Revised code :

1 
2void multiline_textout_v1a(BITMAP* bmp , FONT *font , const char *ml_str , int x , int y , int v_spacing , int fg , int bg ,
3 void (*text_func) (BITMAP* , const FONT* , const char* , int , int , int , int)) {
4 
5 char* copy = strdup(ml_str);
6
7 char* line = copy;
8 char* endline = strchr(line , '\n');
9
10 while(endline) {
11 *endline = '\0';
12 text_func(bmp , font , line , x , y , fg , bg);
13 line = endline + 1;
14 endline = strchr(line , '\n');
15 y += v_spacing;
16 }
17 endline = strchr(line , '\0');
18 if (line != endline) {
19 text_func(bmp , font , line , x , y , fg , bg);
20 }
21
22 free(copy);
23}

 1   2 


Go to: