1. ## String manipulation.

Im having problems with a function of mine. I was just practicing playing with c++ strings, and most of the program works just fine, but after i tried to add a function to calculate the Digit Sum of the numbers in the string, i encountered some weird behaviour.

If i just input the string to be 1, the digit sum is 49, 2 is 50, 3 is 51, and so on. It doesn't really make sense, and the code looks fine to me.

Code:
```#include <iostream>
#include <string>

int ZeroTest(std::string str);
int EvenTest(std::string str);
int OddTest(std::string str);
int StrTotal(std::string str);

int main()
{
int ZeroCount = 0, EvenCount = 0, OddCount = 0, Total = 0;
std::string str;

std::cout << "Enter string to test: ";
std::cin >> str;
std::cout << std::endl;

ZeroCount = ZeroTest(str);
EvenCount = EvenTest(str);
OddCount = OddTest(str);
Total = StrTotal(str);

if((ZeroCount + EvenCount + OddCount) == str.size())
{
std::cout << "Number of zeroes : " << ZeroCount << std::endl;
std::cout << "Number of evens : " << EvenCount << std::endl;
std::cout << "Number of odds : " << OddCount << std::endl << std::endl;
std::cout << "String total is : " << Total << std::endl;
std::cout << "String size is : " << str.size() << std::endl;
}
else
{
std::cerr << "String size error" << std::endl;
}
std::cin.ignore(2);
return 0;
}

int ZeroTest(std::string str)
{
int i = 0, ZeroCount = 0;

for(i; i < str.size(); i++)
{
if(str[i] == '0')
{
ZeroCount++;
}
}
return(ZeroCount);
}

int EvenTest(std::string str)
{
int i = 0, EvenCount = 0;

for(i; i < str.size(); i++)
{
if(str[i] % 2 == false && str[i] != '0')
{
EvenCount++;
}
}
return(EvenCount);
}

int OddTest(std::string str)
{
int i = 0, OddCount = 0;

for(i; i < str.size(); i++)
{
if(str[i] % 2 == true)
{
OddCount++;
}
}
return(OddCount);
}

int StrTotal(std::string str)
{
int i = 0, Total = 0;

while(i < str.size())
{
Total = Total + str[i];
i++;
}
return(Total);
}```

2. When you use a character as an integer, the character's character code is used instead. If you have a digit like '1', you have to convert it to the actual number 1 before you use it in your calculation.

To do this, simply subtract the character '0' from the character in the string and it will give you the correct number.
Code:
`int digit = str[i] - '0';`
By the way, you are just getting "lucky" with your even and odd test. The same problem is happening there, you are checking the character code to see if it is even or odd, not the number itself. On your machine, the character code is even if the digit is even, but that is not guaranteed to happen and a better idea would be to convert to the digit first and then do the work.

3. Originally Posted by Daved
On your machine, the character code is even if the digit is even, but that is not guaranteed to happen and a better idea would be to convert to the digit first and then do the work.
It's not really guaranteed that the characters '0' through '9' have contiguous codes, either. So strictly, subtracting '0' isn't guaranteed to work either. The most portable way to convert from characters to numbers is sscanf() or atoi(), but those work on strings, not single characters, so you have to stick the character in a null-terminated string first.

Of course, I can't think of an example of a real-world character set where '0' through '9' are not contiguous and in-order, so it's not the biggest deal in the world.

4. >> It's not really guaranteed that the characters '0' through '9' have contiguous codes, either.

Actually it is. I don't have time to look it up right now, but the C++ standard guarantees exactly that.

5. What's not guaranteed is having '0' equal to 48, so use '0' instead of the numeric constant 48.

6. Originally Posted by brewbuck
It's not really guaranteed that the characters '0' through '9' have contiguous codes, either. So strictly, subtracting '0' isn't guaranteed to work either.
Actually they are guaranteed to be contiguous. You may be thinking of the letters 'A' through 'Z'.

7. Actually they are guaranteed to be contiguous. You may be thinking of the letters 'A' through 'Z'.
I think brewbuck was referring to character encodings other than ASCII. Tbh I dont see any reason why someone would want to encode numbers in a noncontiguous way, but it surely is possible.

8. No. As Daved and I have mentioned, '0' - '9' are guaranteed to be contiguous, no matter what the character encoding.

Check out the last post of this thread. http://www.ozzu.com/ftopic23794.html

9. Yeah. I see its part of the C++ standard, but if someone was bent on creating some kind of character encoding that did not have contiguous numbers it still should be possible. Somehow. Not that its ever going to happen.

10. Apparently it isn't. You're right, though. The standard should have included a tonumber() macro/function, usually defined like this:
Code:
`#define tonumber(c) (isdigit(c) ? (c) - '0' : -1)`
Well, they didn't. Too late now.

And if '0' - '9' have to be contiguous, why can 'a' - 'z' be non-contiguous? . . .

11. Originally Posted by mike_g
but if someone was bent on creating some kind of character encoding that did not have contiguous numbers it still should be possible.
Then the C++ implementor (compiler writer) would not be able to use that character set.

12. Originally Posted by dwks
And if '0' - '9' have to be contiguous, why can 'a' - 'z' be non-contiguous? . . .
IBM?

13. >> And if '0' - '9' have to be contiguous, why can 'a' - 'z' be non-contiguous?
Because there are many character sets that don't just use the english 'a' - 'z', but there aren't any number systems that use '0' - '9' in a different order or with extra characters inserted. I don't know if that is the real reason, but its good enough for me.

14. but there aren't any number systems that use '0' - '9' in a different order or with extra characters inserted.

I know what you mean, though.

15. Originally Posted by Daved
When you use a character as an integer, the character's character code is used instead. If you have a digit like '1', you have to convert it to the actual number 1 before you use it in your calculation.

To do this, simply subtract the character '0' from the character in the string and it will give you the correct number.
Thanks alot, the Digit Sum function is working correctly now.

Originally Posted by brewbuck
It's not really guaranteed that the characters '0' through '9' have contiguous codes, either. So strictly, subtracting '0' isn't guaranteed to work either. The most portable way to convert from characters to numbers is sscanf() or atoi(), but those work on strings, not single characters, so you have to stick the character in a null-terminated string first.

Of course, I can't think of an example of a real-world character set where '0' through '9' are not contiguous and in-order, so it's not the biggest deal in the world.
Isn't there a function for converting a single char to an int? Or couldn't i just cast the char to an int? Would that help?