Converting a char to an int

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • JSchaenzle
    New Member
    • Sep 2009
    • 4

    Converting a char to an int

    I am trying use the following code to convert a char to an int but it's not working.
    For some reason PosToMoveTo contains 4000 instead of 4. I am not sure why...

    main()
    {
    int i;
    int dis;
    char * Distance;
    char N0, N1, N2, N3, N4;
    int PosToMoveTo;
    ReceivedStr = "P0004";

    N0 = ReceivedStr[0];
    N1 = ReceivedStr[1];
    N2 = ReceivedStr[2];
    N3 = ReceivedStr[3];
    N4 = ReceivedStr[4];

    switch(N0)
    {
    case 'R':
    break;
    case 'P':
    PosToMoveTo = atoi(&N4);
    if(MoveToPos(Po sToMoveTo) == 'T')
    {
    break;
    }
    break;
    case 'T':
    break;
    default:
    break;
    }

    Can someone please explain what I am doing wrong?
  • DelphiCoder
    New Member
    • Jul 2009
    • 24

    #2
    Instead of:
    PosToMoveTo = atoi(&N4);

    You can try:
    PosToMoveTo = (int) N4 - 48;

    I believe that atoi() expects a null-terminated string. A char is not necessarily followed by a null terminator in memory, so when you give atoi a pointer to a char, it just keeps reading the contents of memory until it hits the null-terminator. It doesn't know that the length of your "string" is just one character.

    Comment

    • DelphiCoder
      New Member
      • Jul 2009
      • 24

      #3
      By the way, I just tried your code in Visual C++ 2008, and it actually works just fine as is. The value of N4 is 4 (not 4000). The only thing I changed is I added (char *) before ReceivedStr:

      char *ReceivedStr = "P0004";

      But what I said earlier is still true if I'm understanding the C spec correctly. According to the specification of the C language, atoi requires a null-terminated string.

      Comment

      • JSchaenzle
        New Member
        • Sep 2009
        • 4

        #4
        Thanks, I am trying to program a "Rabbit" mcu and it uses a language called Dynamic C, which is JUST like C. Your suggestion with the N4 - 48 worked. I think the problem is like you say, atoi() is looking for a null terminated string and when I pass it a single character it is not null terminated...

        Comment

        • donbock
          Recognized Expert Top Contributor
          • Mar 2008
          • 2427

          #5
          I'm going to suggest something a bit more complicated -- with error checking and slightly more portable source code.

          I hope the moderators will see this as something other than spoonfeeding ...
          Code:
          #include <ctype.h>
          
          /* Convert encoded digit character to equivalent integer value */
          /* Return negative value if input is not a digit character */
          int convert(char c) {
             if (isdigit(c)) {
                /* Assume digits are encoded sequentially, starting from '0'. */
                return (int) (c - '0');
             } else {
                /* Illegal input.  Return a negative value. */
                return -1;
             }
          }
          What am I doing that's different from what you've already got?
          1. Use isdigit to confirm the input character is legal.
          2. Specified clear and unambiguous behavior expected if the input is illegal.
          3. Use character constant '0' instead of the magic number 48. Doing so helps to document the algorithm and relieves me of the need to memorize the ASCII table. For that matter, '0' will have the right value even for platforms that don't use ASCII character encoding.
          4. Added comments.

          Did using '0' instead of 48 make the code portable? Well ... perhaps not. I don't believe the Standard requires character encodings for digits be sequential starting at '0'.

          Comment

          • Banfa
            Recognized Expert Expert
            • Feb 2006
            • 9067

            #6
            Originally posted by donbock
            Did using '0' instead of 48 make the code portable? Well ... perhaps not. I don't believe the Standard requires character encodings for digits be sequential starting at '0'.
            Read your specification Don. I believe the standard does require that the character digits '0', '1' ... '9' should be sequential (or at least should act under arithmetic as if they are). What it doesn't doesn't require is that any of the other digits specifically letters, have the same relationship. That is that 'A' - 'B' does not have to equal 1 and the same for any other 2 letters. Some character coding, e.g. EBCDIC, actually do not have the entire alphabet in sequence however it is not uncommon for programmers to assume that they are.

            Comment

            • donbock
              Recognized Expert Top Contributor
              • Mar 2008
              • 2427

              #7
              Originally posted by Banfa
              Read your specification Don. I believe the standard does require that the character digits '0', '1' ... '9' should be sequential (or at least should act under arithmetic as if they are).
              OK, you shamed into getting off the couch and looking it up.
              Originally posted by C99
              5.2.1 Character sets
              ...
              In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous.
              ...
              Banfa is correct, the code I provided in reply #5 is marvelously portable; and I don't care who knows it!
              Stop it -- I'm blushing.

              Comment

              • DelphiCoder
                New Member
                • Jul 2009
                • 24

                #8
                If you're really concerned, you can just write a function like this:

                Code:
                int CharToInt(char c)
                {
                   char digits[] = "0123456789";
                   int i;
                   for (i=0; i<=9; i++)
                      if (c == digits[i])
                         return i;
                   return -1;
                }
                Or perhaps this:
                Code:
                int CharToInt2(char c)
                {
                   char *digits = "0123456789";
                   char *pos = strchr(digits, c);
                
                   return (pos != NULL) ? (pos - digits) : -1;
                }

                Comment

                Working...