Thread: Converting Numeric Characters to Hex

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    7

    Converting Numeric Characters to Hex

    Sorry for a probably stupid question. I'm pretty new to this.

    Anyway I'm writing a simple program to combine multiple files into one large file (used in certain Wii games). I've got most of it done, but I'm having trouble trying to convert a regular character into hex to be written to the file.

    One of the arguments I ask for is the number of files to be combined. So for three files the user would type "3". However, it's stored as a character, so when I try to write it itgets written as 0x33 instead of 0x03 as I need it. I've tried typecasting it as an integer but that closest I've gotten it is 0x30. Technically the total number is supposed to be 2 bytes (0x0003), though I doubt the first will ever need to be used.

    Unfortunately I don't really have any relevant code to post, but any help would be appreciated (I'm sure it's something simple).

    Thanks.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you're reading in with a character, I guess you could subtract '0' to get the value of the number.

  3. #3
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Also, a character its just a 2 byte (or 1 byte) variable. It has to do with size. Hex is just how you translate a value from the basic binary format (maybe not a good terminology here).
    So you have to know what type of variables Wii uses. I am saying this because a file will just be a 00101010010101010...1000101 thing. If you read one, one byte or two two bytes or whatever depends the type you tell it to read. If you tell to read an 4 byte int it will read 4 bytes and store them in a memory space and tag them as a int.

    So you can do as suggested and substract '0'. Also a char uses ' ' and not " "

    And isn't char 1 byte?

    And I have no idea how you get 0x30 from casting it to an int
    Last edited by C_ntua; 11-19-2008 at 11:36 AM.

  4. #4
    Registered User
    Join Date
    Nov 2008
    Posts
    7
    Thanks for your help.

    Hmm, well I tried the subtract '0' thing, but I got an error "cannot convert char to char". Here is the code I was trying to use:

    Code:
             ofstream output ( argv[argc-1], ios::out | ios::trunc | ios::binary );
             PacHeader[0] = '\0';
             strcat ( PacHeader, "ARC" );
             output.write (PacHeader, 3);
             output.seekp( 0x07 );
             argv[2] = argv[2] - '0';
             output.write ( argv[2], 1);
             output.seekp( 0x40 );
    As for what the Wii will read, the file is pretty basic.

    Main header:
    0x00 [4] = 'ARC\0'
    0x06 [2] = Number of files (3 = 0x0003, 15 = 0x000F, etc)
    0x10 [48] = File name

    File header:
    0x04 [4] = Size of file
    0x20 = File data

    Anything else isn't important and can just be filled with null bytes. I can get it to write everything else, since it is all either copied from another file or is already a string of characters, however since this one byte must be user entered, it can't be written as entered since it will give the hex value of 3 (0x33) rather than the byte 0x03. I know I'm still not explaining it well, but I don't know how else to put it.
    Last edited by Pharrox; 11-19-2008 at 12:30 PM.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
             PacHeader[0] = '\0';
             strcat ( PacHeader, "ARC" );
    can bet written as
    Code:
             strcpy ( PacHeader, "ARC" );
    Code:
             output.write (PacHeader, 3);
    Does not match:
    Code:
    0x00 [4] = 'ARC\0'
    as the latter is 4 bytes, and you write 3 bytes.

    My guess is that:
    "cannot convert char to char"
    should be
    "cannot convert char* to char"
    since you are trying to do that in this line:
    Code:
             FileAmount = argv[2] - '0';
    argv[2] is a char * (that is, a text string), not a single char.

    You probably want to use strtol() to convert argv[2] to an integer value (it does not at all have to be a hex value - you need a short integer).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Nov 2008
    Posts
    7
    As for only writing three bytes instead of four, the fourth will always be null so it doesn't really need to be specified by the program.

    I figured out what was causing the char to char error, but subtracting '0' just makes it write a null byte for some reason. I'll try using strtol() and edit this post with the results

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Pharrox View Post
    As for only writing three bytes instead of four, the fourth will always be null so it doesn't really need to be specified by the program.
    Yes, but you NEED to store the null byte, otherwise the code reading the information will read some other byte when it reads the 4 bytes in to check the value.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Nov 2008
    Posts
    7
    Well I got strtol() to work, but I still have to problem of how to get it to write to the file. Since file.write() only accepts arguments of character arrays I tried typecasting the integer as const*. It compiled fine but crashed when run. Since it would need to appear as a character anyway, wouldn't it still ouput as 0x33?

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You need to pass the ADDRESS of your integer (which should be of the type short or unsigned short), and then cast that to char *.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Just another take on the problem: it seems to me that you have a null terminated string that is the textual input of the number of files. You want to write this to the output file in hexadecimal notation.

    This suggests a two step process: first, convert the null terminated string to an integer, and then write that integer to file file output stream formatted in hexadecimal, e.g.,
    Code:
    const char num_files_as_text[] = "3";
    std::stringstream ss(num_files_as_text);
    int num_files;
    ss >> num_files;
    output << "0x" << std::setfill('0') << std::setw(4)
        << std::hex << std::noshowbase << num_files;
    where output is the ofstream in your own example, and you need to #include <iomanip> and <sstream>.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Nov 2008
    Posts
    7
    Well now I feel like a complete idiot. That was exactly what I was doing wrong. Well it all seems to be working now and the rest should be pretty easy.

    Thanks a ton for all your help.

  12. #12
    Registered User
    Join Date
    Nov 2008
    Posts
    7
    Okay, one more quick question.

    How can I write a stream of bytes in reverse? There are four bytes I need to write but they always output as 4321 instead of 1234.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Pharrox View Post
    Okay, one more quick question.

    How can I write a stream of bytes in reverse? There are four bytes I need to write but they always output as 4321 instead of 1234.
    You either have to do lots of seekp() or reverse it before you write it. The latter is huge number of times faster than the former.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Registered User
    Join Date
    Nov 2008
    Posts
    7
    Actually I'm trying to write another integer (the size of the file). If I typecast that the same way as my previous problem it will write in reverse. I tried putting it into another character array, reversing that, and writing to the file, but all the data got changed. Since it's actually writing an integer, how would I reverse it before writing?

    EDIT: I just tested it again and it seems like it messes up the data on the first pass but the rest are fine. I think I may just have to change the order in which it does some things.
    Last edited by Pharrox; 11-20-2008 at 11:02 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 10
    Last Post: 07-10-2008, 03:45 PM
  2. displaying hex characters
    By pastitprogram in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 02:18 PM
  3. converting an int into hex and memcpy
    By puppy in forum C Programming
    Replies: 10
    Last Post: 07-03-2006, 11:39 AM
  4. Replies: 11
    Last Post: 03-24-2006, 11:26 AM
  5. converting hex to dec
    By jibbles in forum C Programming
    Replies: 20
    Last Post: 08-07-2004, 11:40 PM