Allegro.cc Forums » Programming Questions » Extracting digits from a integer

 Extracting digits from a integer
 CIRCLE Member #5,301 December 2004 Answers in this post are>> ``` int score = 656; char scorestring[50]; snprintf(scorestring, sizeof(scorestring), "%d", score); int scorelength = strlen(scorestring); for (scoredigit = 0; scoredigit < scorelength; scoredigit++) { textprintf_ex(activepage, font, 0 + (scoredigit * 17), 0, makecol(255, 255, 255), -1, "%i", scorestring[((scorelength - 1) - scoredigit)] - 48); } ``` also replacing the snprintf(scorestring, sizeof(scorestring), "%d", score); with ``` itoa(score, scorestring, 10); ``` will do the same thing. But it is considered non standard.Original question.I am using a new numbering system in my game where as before I just put the text on the screen. What I can not figure out is how to.1. Find out how many places my score uses. I.E. If score was 1423 it would be 4 places2. How to take just 1 number from the score. I.E. 1423 is the score and I wanted just the 3rd number I would have 4.I used to have an old program in Qb that a Binary number and made it decimal. Dont know how acurate it was but it did what I am looking for or close to it.```DIM BinNum(1 TO 300) AS STRING, NStringNum(1 TO 300) AS LONG CLS INPUT "Binary String:_ ", BinNum\$ FOR LoopStart = 1 TO LEN(BinNum\$) BinNum\$(LoopStart) = MID\$(BinNum\$, LoopStart, 1) NStringNum(LoopStart) = VAL(BinNum\$(LoopStart)) NEXT FOR LoopStart = 1 TO LEN(BinNum\$) DecimalNum = DecimalNum + NStringNum(LoopStart) * (2 ^ (LEN(BinNum\$) - LoopStart)) NEXT PRINT DecimalNum ``` other then the example I don't know what it is called if even pointed in the correct direction I could do a little research on it. But I never really learned more then the basics of C/C++ and when straight into allegro. -I edit a lot. Prepare thyself.
 HardTranceFan Member #7,317 June 2006 sprintf(someChar, "%i", score)?And then work with someChar to get the lengths and digits. --"Shame your mind don't shine like your possessions do" - Faithless (I want more part 1)
 Matthew Leverton Supreme Loser January 1999 For positive numbers: ```int digit_count = (int)log10(num) + 1; int digit_value = (int)(num / pow(10, place)) % 10; ```
 Jakub Wasilewski Member #3,653 June 2003 Quote: int digit_count = (int)log10(num) + 1; Just don't try it on 0. ---------------------------[ ChristmasHack! | My games ] :::: One CSS to style them all, One Javascript to script them, / One HTML to bring them all and in the browser bind them / In the Land of Fantasy where Standards mean something.
 CIRCLE Member #5,301 December 2004 Thanks that was what was needed```digit_count = (int)log10(score) + 1; ``` ```digit_value = (int)(score / pow(10, 1)) % 10; ``` ```textprintf_ex(active_page, font, 0, 0, makecol(255, 255, 255), -1, "Digits in score %i Digit Value %i", digit_count, digit_value); ``` Only thing is if score is 0 digit_count returns a large negitive number but that is easy to get around with a simple check if the number is not positive just post a 0 score.Thanks a lot.Well at the very beginning of the game the score is going to be 0 so that value will be returned until the score is >0Finished Result: ```digit_count = (int)log10(score + totalscore) + 1; for (scoredigit = 0; digit_count > scoredigit; scoredigit++) { draw_sprite(active_page, numbers[(int)((score + totalscore) / pow(10, scoredigit)) % 10], 275 - scoredigit *17, 15); } digit_count = (int)log10(lives) + 1; if ((int)log10(lives) + 1 < 0) draw_sprite(active_page, numbers[0], 275, 15); for (livesdigit = 0; (int)log10(lives) + 1 > livesdigit; livesdigit++) { draw_sprite(active_page, numbers[(int)(lives / pow(10, livesdigit)) % 10], 100 - livesdigit *17, 15); } ``` I have one last problem with this though if score + totalscore = 1000 it passes 0000 and if score + totalscore = 2000 it passes 1000 till 10000 it passes 19000 for some reason the 4th digit doesn't display properly until the score = 1001 and so on. I don't see where the problem is any one else?Some where in here is the problem I just can't seem to isolate it.```digit_count = (int)log10(score + totalscore) + 1; for (scoredigit = 0; digit_count > scoredigit; scoredigit++) { draw_sprite(active_page, numbers[(int)((score + totalscore) / pow(10, scoredigit)) % 10], 275 - scoredigit *17, 15); } ``` -I edit a lot. Prepare thyself.
 Matthew Leverton Supreme Loser January 1999 I wondered if you were doing something like this. It seems to me that you are reinventing the printf function: ```myfont = load_font("font.bmp"); textprintf_right_ex(active_page, myfont, 275,15, -1, -1, "%d", score); ``` The above assumes a multi-color font. Replace the first -1 by the color if your font is a solid color.If you really must do your own thing here (and I doubt it), I'd stick with the sprintf way because it's easier to read: ```char score_str[100]; sprintf(score_str, "%i", score); int x = 275, y = 15; for (int i=strlen(score_str)-1; i>=0; --i) { int digit_value = score_str - '0'; draw_sprite(active_page, numbers[digit_value], x, y); x-= 17; } ```
piccolo
Member #3,163
January 2003

 1 //cant remember header file c++ 2 3 4 extern string NumberToString(int Number) 5 { 6 ostringstream converter; 7 converter << Number; 8 return converter.str(); 9 } 10 11 int num= 346; 12 13 if(NumberToString(num)[0]=='0') 14 { 15 16 } 17 if(NumberToString(num)[0]=='1') 18 { 19 20 }

Edit: wow i type slow 3 post came out of nowhere
Edit2: i think my way is better because you can get ohold of the 1st 2nd and nth numbers

Edit3:

Quote:

the 4th digit doesn't display properly until the score = 1001 and so on. I don't

i think your bug lie in the (int) casting

wow
-------------------------------
i am who you are not am i

 CIRCLE Member #5,301 December 2004 Quote: i think your bug lie in the (int) casting explaing please.Whats odd is that if I```draw_sprite(active_page, numbers[(int)((score + totalscore) / pow(10, 3)) % 10], 275 - scoredigit *17, 15); ``` instead of...```draw_sprite(active_page, numbers[(int)((score + totalscore) / pow(10, scoredigit)) % 10], 275 - scoredigit *17, 15); ``` It shows the value as correct and if I use ```textprintf_ex(screen, font, SCREEN_W/2 - (4*19) - scoredigit * 30, SCREEN_H/2, makecol(255,255,255), -1, "%i ", scoredigit); ``` it also shows the correct values but when I use the variables only the thousands place is messed up and only when the value is exact 1000,2000,10000 ect. -I edit a lot. Prepare thyself.
Edgar Reynaldo
Major Reynaldo
May 2007

Hey Circle , this might help.

Until I decide to write my own function to convert integers into strings , I've been using Itoa

http://www.cplusplus.com/reference/clibrary/cstdlib/itoa.html

Example

 1 int score = 12345; 2 char numberstring[50]; 3 for (x = 0 ; x < 50 ; x++) {numberstring[x] = '\0';} 4 5 itoa(score , numberstring , 10); 6 7 // Now "12345" is stored in numberstring 8 // use strlen to find out it is 5 digits 9 // then access the digit like this 10 int score_length = strlen(numberstring); 11 12 // example if you want the hundreds digit this will access it 13 numberstring[((score_length - 1) - 2)]; 14 15 // If you are looking for the 10^x digit place this should do it 16 numberstring[((score_length - 1) - x)]; 17 // x = 0 is ones place and so on.

Then if you wanted to convert the digit you found from numberstring use
atoi (in stdlib.h) to change it back to an integer.

 CIRCLE Member #5,301 December 2004 Ok BIG thanks for all the help from everyone you all are great. Ended up with ```itoa(score + totalscore, scorestring, 10); itoa(lives, livesstring, 10); int score_length = strlen(scorestring); int lives_length = strlen(livesstring); for (scoredigit = 0; scoredigit < score_length; scoredigit++) { draw_sprite(active_page, numbers[scorestring[((score_length - 1) - scoredigit)]- 48], 275 - scoredigit *17, 15); textprintf_ex(screen, font, SCREEN_W/2 - (4*19) - scoredigit * 30, SCREEN_H/2, makecol(255,255,255), -1, "%i ", scorestring[((score_length - 1) - scoredigit)]- 48); } for (livesdigit = 0; livesdigit < lives_length; livesdigit++) { draw_sprite(active_page, numbers[livesstring[((lives_length - 1) - livesdigit)]- 48], 100 - livesdigit *17, 15); } ``` Works fantastic now and the 4th digit errors are gone. Odd I am still using all the same variables. Besides digit_value and digit_count but they were just replaced with lives_length and score_length and either way still worked with the iota. I also decided to skip a lot of work and just subtract 48 from the itoa value to get the correct numbers I needed. -I edit a lot. Prepare thyself.
 gnolam Member #2,030 March 2002 I suggest you use snprintf() instead of itoa(). itoa() is non-standard. Plus, you get some extra memory safety you wouldn't get otherwise.[EDIT] Quote: textprintf_ex(screen, font, SCREEN_W/2 - (4*19) - scoredigit * 30, SCREEN_H/2, makecol(255,255,255), -1, "%i ", scorestring[((score_length - 1) - scoredigit)]- 48); You're transforming the digit into ASCII, then transforming it into an integer, and then printing it (which will, again, transform it into ASCII). Just print it as a char instead.textprintf_ex(screen, font, SCREEN_W/2 - (4*19) - scoredigit * 30, SCREEN_H/2, makecol(255,255,255), -1, "%c", scorestring[(score_length - 1) - scoredigit]);And might I suggest you stop draw directly to the screen? Use a buffer of some kind. -- Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!
 CIRCLE Member #5,301 December 2004 the part that posts to the screen is my test line. It is removed when things are working correctly. every thing else uses buffers.I am using bitmaps to place the numbers on the screen instead of dealing with fonts. -I edit a lot. Prepare thyself.
 HardTranceFan Member #7,317 June 2006 You can have an allegro font and replace the digit bitmaps in that font with your own digit bitmaps. That would save you the hassle of rewriting the functionality (well, too late now ), but it may also be faster. --"Shame your mind don't shine like your possessions do" - Faithless (I want more part 1)
 Tobias Dammers Member #2,604 August 2002 Quote: I suggest you use snprintf() Please, please, please, follow this advice.And use qualifiers on the snprintf call. For example, if you want to display a score acrade-style, with a maximum of 8 digits, and leading zeroes, you'd do: ```snprintf(buf, "%08.8i", score); ``` ---Me make music: Triofobie---"We need Tobias and his awesome trombone, too." - Johan HalmÃ©n
 Ron Ofir Member #2,357 May 2002 Quote: itoa() is non-standard. Nooo!! My whole world just collapsed...
CIRCLE
Member #5,301
December 2004

Only one problem the snprintf makes no sence to me in

```int snprintf (char *buffer, size_t n, const char *format,
...);
```

format. I was for some reason never able to completely understand those. How ever if you have a small example I seem to understand those easier.

 1 itoa(score + totalscore, scorestring, 10); 2 itoa(lives, livesstring, 10); 3 itoa(mouseh, mousehstring, 10); 4 int scorelength = strlen(scorestring); 5 int liveslength = strlen(livesstring); 6 int mousehlength = strlen(mousehstring); 7 for (mousehdigit = 0; mousehdigit < mousehlength; mousehdigit++) 8 { 9 stretch_sprite(activepage, numbers[mousehstring[((mousehlength - 1) - mousehdigit)] - 48], 500 - mousehdigit * 10, 12, 10, 10); 10 } 11 for (scoredigit = 0; scoredigit < scorelength; scoredigit++) 12 { 13 draw_sprite(activepage, numbers[scorestring[((scorelength - 1) - scoredigit)] - 48], 275 - scoredigit *17, 15); 14 } 15 for (livesdigit = 0; livesdigit < liveslength; livesdigit++) 16 { 17 draw_sprite(activepage, numbers[livesstring[((liveslength - 1) - livesdigit)] - 48], 100 - livesdigit *17, 15); 18 }

currently this is what I am using and it works. Maybe there is something else besides itoa that I can use and keep much this same code?

-I edit a lot. Prepare thyself.

 LennyLen Member #5,313 December 2004 Quote: lease, please, please, follow this advice.And use qualifiers on the snprintf call. For example, if you want to display a score acrade-style, with a maximum of 8 digits, and leading zeroes, you'd do:snprintf(buf, "%08.8i", score); You've missed a parameter there.Quote: I was for some reason never able to completely understand those. How ever if you have a small example I seem to understand those easier.currently this is what I am using and it works. Maybe there is something else besides itoa that I can use and keep much this same code? Replace the first two lines with:```snprintf(livestring, sizeof(livestring), "%d", score + totalscore); snprintf(mousehstring, sizeof(mousehstring), "&d", mouseh); ``` The first parameter of snprintf() is the character array (string) you're writing to, the second parameter is the maximum number of characters to write (though, it will actually copy this ammount minus one characters, since it appends a null terminator). From there after, you write a format specifier, and supply additional variables, as you would to any of the printf() variants.
 CIRCLE Member #5,301 December 2004 LennyLen said: The first parameter of snprintf() is the character array (string) you're writing to, the second parameter is the maximum number of characters to write (though, it will actually copy this ammount minus one characters, since it appends a null terminator). From there after, you write a format specifier, and supply additional variables, as you would to any of the printf() variants. Now that I understand. ^^But actually it would be ```snprintf(livesstring, sizeof(livesstring), "%d", lives); snprintf(mousehstring, sizeof(mousehstring), "%d", mouseh); snprintf(scorestring, sizeof(scorestring), "%d", score); ``` works great and easier to understand. Thanks. Why is the mouseh given a &d instead of %d in your example and livesstring getting the value from score + totalscore. Although I like the mistakes. I think it gave me an error because my int wasn't given enough space to hold &mouseh. and when the score and lives went up at the same time that was just a given. -I edit a lot. Prepare thyself.
 LennyLen Member #5,313 December 2004 Quote: Why is the mouseh given a &d instead of %d in your example Because it was 2am, and I'd been drinking for a couple of hours. They should of course both be %d, as you figured out.Quote: and livesstring getting the value from score + totalscore. Same as above.Quote: I think it gave me an error because my int wasn't given enough space to hold &mouseh. There was no &mouseh in my example. The line I wrote should have just given you a warning about having too many format arguments.
 CIRCLE Member #5,301 December 2004 Well anyways it was tons of help. Thanks. -I edit a lot. Prepare thyself.
 Go to: Allegro Development Installation, Setup & Configuration Allegro.cc Comments Off-Topic Ordeals The Depot Game Design & Concepts Programming Questions Recent Threads