0

Right now I have a u8 array that I successfully converted to a hexidecimal char array. Now, trying to change it back into a u8 array has been a doozy. I tried this code:

        // DEMO:
        char *message = "0f236a1f";
        int i;
        u8 final[4];
        memset(final, 0, 4);
        char* part = "00";
        for (i = 0; i < 4; i++)
        {
            memcpy(part, &message[i*2], 2);
            u8 num = 0;
            sscanf(part, "%x", &num);
            printf("%i", num); 
            final[i] = num;
        }

I prepopulate everything with values to prevent stay memory values from messing up large portions of zeros I have in my actual data. Despite everything I have tried, occasionally the wrong values are assigned, and I can't find any other method online which does the same thing. Help me if you can, I hate C.

EDIT:

I revised my code, and am showing the real thing now, to see if it helps. The variable message is 464 zeros in a giant char * array. The console is still occasionally printing numbers besides zero, not sure why:

        int i;
        u8 final[232];
        memset(final, 0, 232);
        char part[3] = "00";
        part[2] = 0;
        for (i = 0; i < 232; i++)
        {
            memcpy(part, &message[i*2], 2);
            unsigned int num = 0;
            sscanf(part, "%x", &num);
            printf("%i", num); 
            final[i] = (u8)num;
        }
omikes
  • 8,064
  • 8
  • 37
  • 50
  • 2
    it appears you are trying to modify a string literal with this line `memcpy(part, &message[i*2], 2);`, since part is initialized with a string literal `char* part = "00";`. That's illegal in C. – Bobby Sacamano Nov 24 '15 at 00:18
  • should it just be char *part[2]; instead? – omikes Nov 24 '15 at 00:19
  • 2
    @BobbySacamano Not modifying a string literal See here: http://stackoverflow.com/questions/718477/string-literals but it is still undefined behavior. – Fantastic Mr Fox Nov 24 '15 at 00:19
  • 2
    `char part[3] = "00"`. You need to allocate enough space for the null. – AShelly Nov 24 '15 at 00:20
  • 1
    @oMiKeY Read a good tutorial on `cstrings`. – Fantastic Mr Fox Nov 24 '15 at 00:20
  • @oMiKeY Understanding how is a string laidout in memory and what constitutes a [tag:c-strings] in the [tag:c] would help you a lot in learning how to do things in general in the [tag:c] language. – Iharob Al Asimi Nov 24 '15 at 00:26
  • 2
    Also, using `sscanf` with `%x` requires a pointer to an `unsigned int`, not `u8`. – nwellnhof Nov 24 '15 at 00:27
  • if I can't use sscanf with %x, is there an alternative that uses u8? I am stuck with u8, unfortunately – omikes Nov 24 '15 at 00:32
  • if you change num to `unsigned int` type and then add a cast to `u8` in the assignement of `final[i]`, that'll do what you're looking for. When you're assigning a larger integer type to a smaller one, the only danger is overflow, which is not a problem in this case. – Bobby Sacamano Nov 24 '15 at 00:40
  • ok I just tried this, but with int instead of unsigned int. it didn't work, but I just made the correction. is it likely to make a difference? – omikes Nov 24 '15 at 00:41
  • @oMiKeY using `int` instead of `unsigned int` will probably work, but it's a bad idea to be using signed data type to represent unsigned data. What didn't work when you changed it? – Bobby Sacamano Nov 24 '15 at 00:43
  • It starts off with a TON of values, then lots of zeros, then just the occasional 13. I'm stepping into somebody elses memory here... – omikes Nov 24 '15 at 01:04
  • In the updated code, you should check the return value of `sscanf` before going on to use `num`. – M.M Nov 24 '15 at 01:48

1 Answers1

3

You are creating undefined behavior with these lines:

    char* part = "00";
    for (i = 0; i < 4; i++)
    {
        memcpy(part, &message[i*2], 2);
        ...
        sscanf(part, "%x", &num);

part points to read only memory (this is why with strings like this we usually declare them as const char* to cause a compiler error when modification attempts occur) More info here.

You should allocate enough space for your string and null terminator with:

char part[3] = "00";
Community
  • 1
  • 1
Fantastic Mr Fox
  • 32,495
  • 27
  • 95
  • 175
  • Why is `part` not a string literal? In fact `part` is a string literal and that's the reason for undefined behavior. Don't be confused with the missing `const` `"00"` is a string literal and `part` is just a non `const` pointer to it. – Iharob Al Asimi Nov 24 '15 at 00:23
  • @iharob `part` is initialized with a string literal (ie `"00"`) but it is not a string literal. At least i think so from here: http://en.cppreference.com/w/cpp/language/string_literal. Also thanks for correcting my typo. – Fantastic Mr Fox Nov 24 '15 at 00:26
  • Don't use [tag:c++] resources to learn [tag:c]. They are different languges despite the similar syntax. And in that link I could confirm that. It makes me hate c++ a little more now. – Iharob Al Asimi Nov 24 '15 at 00:27
  • @iharob Eager to learn, do you have a link for definition of `c` string literal? After a quick search i couldn't find any that convinced me of this. Just forums and hearsay ... – Fantastic Mr Fox Nov 24 '15 at 00:29
  • Read the standard document, just google "*c standard draft n1570*". Please not that `part` is not a string literal per-se it's pointing to one, so conceptually it's correct but "*while not a string literal is stored in read only memory*" is wrong since it's pointing to a string literal. – Iharob Al Asimi Nov 24 '15 at 00:31
  • Yes but, there will be no compiler error with `const` just a warning. I had already upvoted BTW. – Iharob Al Asimi Nov 24 '15 at 00:34
  • @iharob Definitely will get an error http://ideone.com/2RTKUc Maybe not on all compilers but any decent one. – Fantastic Mr Fox Nov 24 '15 at 00:37
  • My appologies! You are right and I use *gcc* I should have known this. – Iharob Al Asimi Nov 24 '15 at 00:42
  • My compiler simply through out a warning instead of stopping me. Maybe its time to get off netbeans... – omikes Nov 24 '15 at 00:43
  • 3
    @oMiKeY: Or time to start paying attention to your compiler warnings. – Crowman Nov 24 '15 at 00:50