how to manipulate itoa

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • khairiabdulrahim
    New Member
    • Jan 2009
    • 3

    how to manipulate itoa

    this is my code:

    #include <stdio.h>
    #include <stdlib.h>

    int main ()
    {
    int j;
    char str[33];


    printf ("Enter a character: ");
    scanf ("%2c",&j);
    flushall();


    itoa (j, str, 16);
    printf ("hexadecima l: %s\n", str);


    getchar();
    getchar();
    return 0;
    }

    Q:

    After I enter say 'N1', it will scan my ascii character and put it into address of i. Note that the hex value for character N1 is 4E31.However, when I use itoa, it output the hex value as 314E. Seemed that it reads the last memory and move backward. How do I overcome this problem? It's C language.

    Thanks
  • donbock
    Recognized Expert Top Contributor
    • Mar 2008
    • 2427

    #2
    1. Function itoa is not part of Standard C. However, it is often provided as a nonstandard extension within stdlib.h. Apparently your compiler is one of those that provides it.

    2. It is not a good idea to get in the habit of using nonstandard extensions. Is there any reason why you couldn't use sprintf(...,"%0 4X",...) instead?

    3. Variable j is defined as an integer, but you have scanf writing an array of characters into it. You can expect type inconsistency of this sort to reliably and repeatably get you into trouble about half the time.

    4. Your scanf format string writes two characters into the integer variable. How do you know an integer holds exactly two characters? That is, how do you know that sizeof(int) == 2? You're hard-coding special knowledge about the size of the int type into your program. This special knowledge is not true on all C platforms. Your code is nonportable -- and it is a good idea to avoid that habit too.

    5. Your program prints "314E" when you expect "4E31". Whenever you see a byte swap like this you should immediately suspect an endian mismatch (google "big-endian" and "little-endian"). The endian mismatch occurs because of the type inconsistency noted in #3 above.

    What is it that you want to accomplish with this program? I'm confident there is a portable way to do it.

    Comment

    • khairiabdulrahim
      New Member
      • Jan 2009
      • 3

      #3
      Thank you for your reply. I do appreciate that.

      1. I could use sprintf as you suggested, but that's not the real intention since I will be still getting '314E'.

      2. However, my intention was this:
      - i m reading from a data file.
      - the data consists of only two bytes of data (two characters i.e N1 followed
      by the next data i.e 5T) and so forth.
      - I want to get the difference for these two data in decimal i.e N1 = 45543
      and 5T = 45553 and the difference is 45553 - 45543 = 20.
      - I'm a newbie, so what I did might be wrong, forgive me for that. What I did
      was I tried to
      change these two bytes character (N1) to decimal/hex using itoa(j,str,10)
      for decimal and itoa(j,str,16) for hex.
      - Once I get the decimal conversion, I was thinking then it will be easy to
      just deduct the value to get the difference between these two data.
      - However, since the conversion was swapped (N1 = 4E31 converted to 314E
      by itoa), so the decimal value will be wrong and finally the difference will
      be wrong also.

      3. How do you view this matter? any suggestion to do it the better way?

      4. The reason variable j is defined as integer because if I were to define it as char, the conversion will take place only for character N, but not character 1. As mentioned previously, my intention was to get the decimal conversion of two characters (N1).

      Thank you very much for the help.

      Comment

      • Banfa
        Recognized Expert Expert
        • Feb 2006
        • 9067

        #4
        It seems to me you mistake is in your interpretation of the file contents as printable charcters (rather than binary bytes) and then your conversion from characters to a string of decimal (or hexadecimal) digits.

        To start with the characters N1 (as you say) have the hexadecimal values 4E and 31, interpreted as 4E31 = 20017 decimal not 45543. It is not at all clear how you obtained 45543. Similarly 5T is 3554 hex = 13652 decimal. The difference is 20017 - 13652 = 6365.

        To get the values out of the file, in a portable manor, you need to know which is supposed to be the most significant byte in the file (i.e. is the file big or little endian).

        If the file is big endian (most significant byte first) then you would do something like this pseudo code

        Code:
        int Read2ByteInt()
        {
            Byte1 = ReadByteFromFile
            Byte2 = ReadByteFromFile
        
            return (Byte1 << BITS_IN_BYTE) | Byte2;
        }
        If the file is little endian (least significant byte first) this would look like

        Code:
        int Read2ByteInt()
        {
            Byte1 = ReadByteFromFile
            Byte2 = ReadByteFromFile
        
            return (Byte2 << BITS_IN_BYTE) | Byte1;
        }
        Then you could do the following

        Code:
        OpenFile
        
        Int1 = Read2ByteInt()
        Int2 = Read2ByteInt()
        
        CloseFile
        
        result = Int1 - Int2

        Comment

        • donbock
          Recognized Expert Top Contributor
          • Mar 2008
          • 2427

          #5
          You have another issue to worry about if the file contains signed integers.

          1. The numeric representation used in the file may differ from that used by your compiler. This is a theoretical possibility, but in reality two's-complement representation is almost universal. Nevertheless, you should confirm this.

          2. The width of integers in the file may differ from the width of integers in your compiler. If so (and if two's-complement notation is used), then you need to make sure negative numbers are sign-extended.

          Comment

          • khairiabdulrahim
            New Member
            • Jan 2009
            • 3

            #6
            Thank you very much. Indeed 4E31 = 20017 decimal not 45543, as I just wrote it arbitrarily (I should put it the right way I guess).

            I have tried using bitwise shift operator and it worked.

            thank you very much for your help guys.

            donbock - yes you are right. that's another thing that I need to consider

            Comment

            • donbock
              Recognized Expert Top Contributor
              • Mar 2008
              • 2427

              #7
              Finally, you want to make sure your program handles malformed input files:
              1. Empty input file.
              2. File contains an odd number of bytes.
              3. File contains an odd number of 2-byte integers.
              This last one is only an exception case if you expect the file to contain pairs of 2-byte integers.

              Comment

              Working...