|
Register or have you forgotten your password?
|
|
|
| CH / Science and Technology This is the correct place for open, moderated discussions relating to science and technology. Open to Registered users only. |
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 | ||||||||
|
Premium Member
Join Date: Nov 2005
Posts: 8,666
|
I need to convert a string, which is guaranteed to contain only numbers, to an array of ints. Or at least convert each digit from the string to an int so I can add it to an array. Here's what I was thinking of doing:
str="12345"; int nums = str.length(); for ( int i=0; i<nums; i++ ) { n = atoi( str[i] ); } The effect should be that the for loops runs once for each digit in str (in this case five times) and sets n to the numerical value of str[i]. However, this gives me an error "invalid conversion from `char' to `const char*' ". Is there any way to do this? -- moto
__________________
Code:
10 IT'S THE FINAL COUNTDOWN 20 FOR C = 1 TO 2 30 DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NAAAA 40 DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NA-NA-NAAAAA 50 NEXT C 60 NA-NA-NAAAA 70 NA-NA NA-NA-NA-NA-NAAAA NAAA-NAAAAAAAAAAA 80 GOTO 10 |
||||||||
|
|
|
|
|
#2 | ||||||||
|
Sockologist
![]()
|
Ah, the old gotchas :-D
In C(++) a C style string is simply an array of char (more precisely, a null terminated array). Consequently, for any given C style string, any indexed position is of type char, not the full string (const char*), which is what atoi() is expecting. The same applies to the C++ string<char> when you subscript with the [ ] operator - the individual characters themselves aren't regarded as strings in their own right. What's more, it's almost certain that string<char> is wrapping a dynamically allocated array of char (ie a C style string) anyway. Luckily for you, since char is basically a numeric type, you can do this instead: n = str[i] - '0'; Note carefully the single quotes around the character literal. As the ASCII character set contains 0-9 in a continuous block, this will convert any ASCII character from 0 - 9 to the corresponding integer value. No need for the library call at all.
__________________
OCA This isn't SCSI... This is SATA!!! I have CDO. It's like OCD except all the letters are in ascending order. The way they should be. Core2 Quad Q9450 2.66GHz / X48T / 4GB DDR3 / nVidia GTX275 / Linux x64, AROS, Win64 A1XE 800MHz / 512MB / Radeon 9200 / OS4.1 A1200T BPPC 240MHz / 256MB / Permedia 2 / OS 3.1 - OS3.9, OS4 A1200T Apollo 1240 28MHz / 32MB / Mediator1200 / Voodoo 3000 / OS3.9 A1200D Apollo 1240 25MHz (ejector seat ROM edition) / 32MB |
||||||||
|
|
|
|
|
#3 | ||||||||
|
Premium Member
Join Date: Nov 2005
Posts: 8,666
|
Thanks Karlos! I had actually already tried "int num=scorestr[i]-'0';" but I missed the quotes around the 0 which is subtracted from the character. I thought you were subtracting zero to make it think it was an integer (because it was being used like one), when further reading reveals that you are subtracting the ASCII code '0' to get the value of the digit.
Here is the solution, where "scorestr" is a string containing the player's score: CODE for ( int i=0; i<scorestr.length(); i++ ) { int num=scorestr[i]-'0'; apply_surface( scorestartpos+(i*12), 10, font, screen, &fontClips[ num ] ); } Thanks again -- moto
__________________
Code:
10 IT'S THE FINAL COUNTDOWN 20 FOR C = 1 TO 2 30 DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NAAAA 40 DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NA-NA-NAAAAA 50 NEXT C 60 NA-NA-NAAAA 70 NA-NA NA-NA-NA-NA-NAAAA NAAA-NAAAAAAAAAAA 80 GOTO 10 |
||||||||
|
|
|
|
|
#4 | ||||||||
|
Sockologist
![]()
|
You know, using a string to hold the score is probably something you could eliminate if your score is an integer type to start with:
Code:
int tempScore = playerScore;
int scoreCursor = .... ; // starting at right hand side
int cursorStep = 12;
while ( tempScore>0 )
{
int digit = tempScore%10; // next decimal digit
tempScore /= 10;
apply_surface( scoreCursor, 10, font, screen, &fontClips[ digit ] );
scoreCursor -= cursorStep;
}
-edit- Actually the above assumes the score must be greater than zero to start with. A better version would be: Code:
int tempScore = playerScore;
int scoreCursor = .... ; // starting at right hand side
int cursorStep = 12;
do {
int digit = tempScore%10; // next decimal digit
tempScore /= 10;
apply_surface( scoreCursor, 10, font, screen, &fontClips[ digit ] );
scoreCursor -= cursorStep;
} while (tempScore != 0);
It could probably even negative scores, though I'd need to check the side effects of the number rendering - you'd need to abs() the digit for sure and you'd have to render the minus sign yourself afterwards. But at least the scoreCursor would already be at the right position.
__________________
OCA This isn't SCSI... This is SATA!!! I have CDO. It's like OCD except all the letters are in ascending order. The way they should be. Core2 Quad Q9450 2.66GHz / X48T / 4GB DDR3 / nVidia GTX275 / Linux x64, AROS, Win64 A1XE 800MHz / 512MB / Radeon 9200 / OS4.1 A1200T BPPC 240MHz / 256MB / Permedia 2 / OS 3.1 - OS3.9, OS4 A1200T Apollo 1240 28MHz / 32MB / Mediator1200 / Voodoo 3000 / OS3.9 A1200D Apollo 1240 25MHz (ejector seat ROM edition) / 32MB |
||||||||
|
|
|
|
|
#5 | ||||||||
|
Premium Member
Join Date: Nov 2005
Posts: 8,666
|
Would that be significantly more efficient than converting it to a string, extracting each character and then converting the character back to an int?
-- moto
__________________
Code:
10 IT'S THE FINAL COUNTDOWN 20 FOR C = 1 TO 2 30 DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NAAAA 40 DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NA-NA-NAAAAA 50 NEXT C 60 NA-NA-NAAAA 70 NA-NA NA-NA-NA-NA-NAAAA NAAA-NAAAAAAAAAAA 80 GOTO 10 |
||||||||
|
|
|
|
|
#6 | ||||||||
|
Sockologist
![]()
|
Almost certainly. However, depending on the specification of your machine to start with, who can say wether or not you'd notice?
The worst part of that code is the modulus and division, but your implementation's int to string conversion almost certainly has to do this too. This way, you avoid all the string handling that sits on top. If you wanted to be really 1337, you could show your score in hex, then you can use >>4 instead of /10 and &F instead of %10, thereby saving those pesky cycles
__________________
OCA This isn't SCSI... This is SATA!!! I have CDO. It's like OCD except all the letters are in ascending order. The way they should be. Core2 Quad Q9450 2.66GHz / X48T / 4GB DDR3 / nVidia GTX275 / Linux x64, AROS, Win64 A1XE 800MHz / 512MB / Radeon 9200 / OS4.1 A1200T BPPC 240MHz / 256MB / Permedia 2 / OS 3.1 - OS3.9, OS4 A1200T Apollo 1240 28MHz / 32MB / Mediator1200 / Voodoo 3000 / OS3.9 A1200D Apollo 1240 25MHz (ejector seat ROM edition) / 32MB |
||||||||
|
|
|
|
|
#7 | ||||||||
|
Premium Member
Join Date: Nov 2005
Posts: 8,666
|
The target platform is the GP2X, so the code needs to be as efficient as possible. The GP2X doesn't handle floating point maths well (apparently) so a solution which avoids this might end up more efficient.
In any case, the routine to convert the integer score to a string and then to an array of ints only needs to be run when the score changes. Then all the main loop has to do is iterate through the array of ints and draw the corresponding numbers on the screen. -- moto
__________________
Code:
10 IT'S THE FINAL COUNTDOWN 20 FOR C = 1 TO 2 30 DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NAAAA 40 DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NA-NA-NAAAAA 50 NEXT C 60 NA-NA-NAAAA 70 NA-NA NA-NA-NA-NA-NAAAA NAAA-NAAAAAAAAAAA 80 GOTO 10 |
||||||||
|
|
|
|
|
#8 | ||||||||
|
Sockologist
![]()
|
Well, the method I presented is likely to be significantly faster than the string one, simply because you arent using strings, be they const char* or std::string<char> so yo don't have any of their corresponding (hidden) overheads.
What I am saying is, the int to string conversion alone has to do something like that loop just presented just to turn the integer into a string of ASCII chars (it's likely to be even worse, since it probably has to add '0' to each one and do various other checks too). All this loop depends on is the integer value of the score and you can apply the same "render on change only" strategy to that* If you are coding for efficiency, never make the mistake of "least lines of source code" equates to "most efficient object code". It's often not true at all (unless you are coding in 1 line per instruction assembler anyway )*caveat: If you constantly have to redraw the score text and the score hasn't changed value then the string version has some merit in that it avoids parsing the int repeatedly. You can, however, have an array of the 'digit' values calculated in the loop method which can be used to redraw an unchanged score value even faster. This is basically the same then as iterating your string score, except you wouldnt need the -'0' per character.
__________________
OCA This isn't SCSI... This is SATA!!! I have CDO. It's like OCD except all the letters are in ascending order. The way they should be. Core2 Quad Q9450 2.66GHz / X48T / 4GB DDR3 / nVidia GTX275 / Linux x64, AROS, Win64 A1XE 800MHz / 512MB / Radeon 9200 / OS4.1 A1200T BPPC 240MHz / 256MB / Permedia 2 / OS 3.1 - OS3.9, OS4 A1200T Apollo 1240 28MHz / 32MB / Mediator1200 / Voodoo 3000 / OS3.9 A1200D Apollo 1240 25MHz (ejector seat ROM edition) / 32MB |
||||||||
|
|
|
|
|
#9 | ||||||||
|
Sockologist
![]()
|
You might go for something like this:
Code:
int startCursor = .... ; // right hand side
int cursorStep = 12; // on screen font spacing
int lastScoreLength = 0;
int scoreDigits[MAX_SCORE_DIGITS] = { 0 };
int oldPlayerScore = 0;
int playerScore = 0;
//....
if (oldPlayerScore!=playerScore) {
// redraw with calculation
int tempScore = playerScore;
int scoreCursor = startCursor;
int i = 0;
do {
int digit = tempScore%10; // next decimal digit
tempScore /= 10;
apply_surface( scoreCursor, 10, font, screen, &fontClips[ digit ] );
scoreCursor -= cursorStep;
scoreDigits[i++] = digit;
} while (tempScore != 0);
lastScoreLength = 0;
oldPlayerScore = playerScore;
} else {
// redraw without recalculation
int scoreCursor = startCursor;
for (i=0; i<lastScoreLength; i++) {
apply_surface( scoreCursor, 10, font, screen, &fontClips[ scoreDigits[i] ] );
scoreCursor -= cursorStep;
}
}
__________________
OCA This isn't SCSI... This is SATA!!! I have CDO. It's like OCD except all the letters are in ascending order. The way they should be. Core2 Quad Q9450 2.66GHz / X48T / 4GB DDR3 / nVidia GTX275 / Linux x64, AROS, Win64 A1XE 800MHz / 512MB / Radeon 9200 / OS4.1 A1200T BPPC 240MHz / 256MB / Permedia 2 / OS 3.1 - OS3.9, OS4 A1200T Apollo 1240 28MHz / 32MB / Mediator1200 / Voodoo 3000 / OS3.9 A1200D Apollo 1240 25MHz (ejector seat ROM edition) / 32MB |
||||||||
|
|
|
|
|
#10 | ||||||||
|
Sockologist
![]()
|
Damn you Mark, you're making me think of C/C++ and distracting me from so called "Web 2.0" development...
Pretty soon I'll be in danger of booting up a miggy.
__________________
OCA This isn't SCSI... This is SATA!!! I have CDO. It's like OCD except all the letters are in ascending order. The way they should be. Core2 Quad Q9450 2.66GHz / X48T / 4GB DDR3 / nVidia GTX275 / Linux x64, AROS, Win64 A1XE 800MHz / 512MB / Radeon 9200 / OS4.1 A1200T BPPC 240MHz / 256MB / Permedia 2 / OS 3.1 - OS3.9, OS4 A1200T Apollo 1240 28MHz / 32MB / Mediator1200 / Voodoo 3000 / OS3.9 A1200D Apollo 1240 25MHz (ejector seat ROM edition) / 32MB |
||||||||
|
|
|
|
|
#11 | ||||||||||
|
Premium Member
Join Date: Nov 2005
Posts: 8,666
|
Quote:
![]() Quote:
-- moto
__________________
Code:
10 IT'S THE FINAL COUNTDOWN 20 FOR C = 1 TO 2 30 DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NAAAA 40 DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NA-NA-NAAAAA 50 NEXT C 60 NA-NA-NAAAA 70 NA-NA NA-NA-NA-NA-NAAAA NAAA-NAAAAAAAAAAA 80 GOTO 10 |
||||||||||
|
|
|
|
|
#12 | |||||||||
|
Sockologist
![]()
|
Quote:
Of all the development work I've done, that was surely the most fun. Many times, I'd simply have an idea and I'd just sit down and code to see "what happens if we try this...". So many strange ideas, some of which were even useful ![]() Never have the time now. Financial considerations have crushed all forms of creativity outside the defined constraints of whatever it is I'm working on for someone else :-(
__________________
OCA This isn't SCSI... This is SATA!!! I have CDO. It's like OCD except all the letters are in ascending order. The way they should be. Core2 Quad Q9450 2.66GHz / X48T / 4GB DDR3 / nVidia GTX275 / Linux x64, AROS, Win64 A1XE 800MHz / 512MB / Radeon 9200 / OS4.1 A1200T BPPC 240MHz / 256MB / Permedia 2 / OS 3.1 - OS3.9, OS4 A1200T Apollo 1240 28MHz / 32MB / Mediator1200 / Voodoo 3000 / OS3.9 A1200D Apollo 1240 25MHz (ejector seat ROM edition) / 32MB |
|||||||||
|
|
|
|
|
#13 | |||||||||
|
Premium Member
Join Date: Nov 2005
Posts: 8,666
|
Quote:
-- moto
__________________
Code:
10 IT'S THE FINAL COUNTDOWN 20 FOR C = 1 TO 2 30 DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NAAAA 40 DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NA-NA-NAAAAA 50 NEXT C 60 NA-NA-NAAAA 70 NA-NA NA-NA-NA-NA-NAAAA NAAA-NAAAAAAAAAAA 80 GOTO 10 |
|||||||||
|
|
|
![]() |
| Bookmarks |
| Tags |
| ints , string , convert , array |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Programmable Array Logic (PAL) | mdivancic | Amiga Hardware Issues and discussion | 0 | 10-12-2005 09:27 AM |
| GAH!!!! Help w/passing array of structure to a function... | TheMagicM | Amiga Software Issues and Discussion | 3 | 01-12-2005 05:29 AM |
| Longs, ints and printf (ansi-C) | elendil | Amiga OS -- Development | 7 | 03-15-2004 08:56 AM |
| Finding the address of an array element | Sidewinder | Amiga OS -- Development | 26 | 03-15-2003 09:37 PM |
| Need help with C++ array declarations!!!! | Glaucus | Amiga OS -- Development | 2 | 11-13-2002 12:12 AM |