Welcome, Guest. Please login or register.

Author Topic: C++ - convert string to array of ints  (Read 3876 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: C++ - convert string to array of ints
« on: September 01, 2007, 12:16:43 PM »
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 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 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 - '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.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: C++ - convert string to array of ints
« Reply #1 on: September 01, 2007, 12:30:11 PM »
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: [Select]


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;
}


Note, however, that this method will right align the output and won't zero fill the result, either. That would be easy to add though, just a loop afterwards that renders your "zero" character until you've emitted the required fixed length of digits overall.

-edit-

Actually the above assumes the score must be greater than zero to start with. A better version would be:

Code: [Select]


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);


This version should work with zero score.

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.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: C++ - convert string to array of ints
« Reply #2 on: September 01, 2007, 12:49:26 PM »
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 :lol:
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: C++ - convert string to array of ints
« Reply #3 on: September 01, 2007, 01:05:35 PM »
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 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 :lol:)


*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.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: C++ - convert string to array of ints
« Reply #4 on: September 01, 2007, 01:24:21 PM »
You might go for something like this:

Code: [Select]


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;  
  }
}

int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: C++ - convert string to array of ints
« Reply #5 on: September 01, 2007, 02:19:04 PM »
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.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: C++ - convert string to array of ints
« Reply #6 on: September 01, 2007, 04:58:55 PM »
Quote
You know it's got bad when C++ is a break from what you were doing before


I'm so busy at the moment that the happy days of coding C/C++/assembler on the amiga seems like a distant dream :-(

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 :lol:

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 :-(
int p; // A