1

Anyway have any idea how to do this?

Let's say i have

char x[] = "ABCD";

and i want to put it into an int, so i'll have

int y = 'ABCD';

I can only put individual chars, such as int y = x[0]; The purpose is to find the decimal representation, but i want the decimal representation of "ABCD" not just "A".

Finally i would use sprintf(dest, "%.2u", value); to get the decimal representation of the char.

EDIT:

I dont understand why, but for "ABCD" this code works

//unrolled bit ops
const char* x = "ABCD";
uint32_t y = 0;
y |= (uint32_t(x[0]) << 24); //MSB
y |= (uint32_t(x[1]) << 16);
y |= (uint32_t(x[2]) <<  8);
y |= (uint32_t(x[3]) /*<< 0*/);

however, per instance if i use "(¸þ¶" i dont get the same result.

EDIT2 **:

I've tried your last edit Sam, but it still doesnt work. The value i'm getting is "4294967294" as opposed to "683212470" the correct value. I also did this

int h1 = '(';
int h2 = '¸';
int h3 = 'þ';
int h4 = '¶';

Output:

40
-72
-2
-74

I googled for the complete ascii table, and i found out that for "þ" the value is "254". I suppose it has something to do with this... i also tried with usigned but no good results.

edit3: If i replace const char *x = "(¸þ¶" with int x[] = {40, 184, 254, 182}; (decimal representation of each character, it works. I can understand where things go wrong, but i have no idea how to fix it.

Alexandru Calin
  • 220
  • 2
  • 11
  • Have a look [here](http://stackoverflow.com/questions/1070497/c-convert-hex-string-to-signed-integer) – Tom Knapen Jan 21 '13 at 14:43
  • Use bit shifts and bitwise or (and properly sized unsigned types). – R. Martinho Fernandes Jan 21 '13 at 14:45
  • Just in case you actually use `"(¸þ¶"` within your program, it will break, because the last three chars are multi-byte chars. The compiler should spit out warnings. This question covers how to put special chars into a string literal: http://stackoverflow.com/q/2420780/1175253 – Sam Jan 21 '13 at 18:22

2 Answers2

4

You need to assure int alignment for that char array for a proper cast or do a memcpy into that int. Also take care of the integer's endianness! Furthermore, usage of C99 integer types such as uint32_t, will also help to make your code portable.

See this question for how to convert the bits: strict aliasing and alignment

EDIT:

What R. Martinho Fernandes means, might be this (not tested):

//unrolled bit ops
const char* x = "ABCD";
uint32_t y = 0;
y |= (uint32_t(uint8_t(x[0])) << 24); //MSB
y |= (uint32_t(uint8_t(x[1])) << 16);
y |= (uint32_t(uint8_t(x[2])) <<  8);
y |= (uint32_t(uint8_t(x[3])) /*<< 0*/);

Above example avoids specific code for any endianness

EDIT 2:

For dynamic char arrays (assuming leading zero chars if less than 4 have to be converted):

const char* x = "ABC";
size_t nChars = 3;

assert(0 < nChars && nChars <= sizeof(uint32_t));

uint32_t y = 0;

int shift = (nChars*8)-8;
for(size_t i = 0;i < nChars;++i)
{
    y |= (uint32_t(uint8_t(x[i])) << shift);
    shift -= 8;
}
Community
  • 1
  • 1
Sam
  • 7,778
  • 1
  • 23
  • 49
  • I tried to memcpy into the int uint32_t x; memcpy(&x, value, 4); – Alexandru Calin Jan 21 '13 at 14:49
  • @AlexandruCalin because you are dealing with memory. If you want to deal with *numbers* use operations that handle *numbers* (bit shifts). – R. Martinho Fernandes Jan 21 '13 at 14:51
  • @AlexandruCalin If that gives you "wrong results", please edit your question to state what results you are expecting. – Joel Rondeau Jan 21 '13 at 15:03
  • @Alexandru Calin : Could you please add the hex values for each byte in that string and what integer you've got from them? It seems, that you want to pass 1-4 chars, dynamically. For that, you'd need some sort of offset. – Sam Jan 21 '13 at 15:15
  • I'm sorry, i don't think i understand you; You want me to pass the each byte as hex before shifting? – Alexandru Calin Jan 21 '13 at 15:25
  • No, I meant showing us the hex values, both expected values and actual input/output values using a debugger (basically what Joel Rondeau said). But you may see the edit first. – Sam Jan 21 '13 at 15:30
  • I just got out of work, ill test it in 10 mins when i get home. Thank you for your quick responses! – Alexandru Calin Jan 21 '13 at 15:40
  • You guessed right, it has to do with the sign bit. The chars need to be unsigned if they're 8bit (extended) ASCII and not 7bit ASCII. See fixes. You could also cast `const char*` to `const unsigned char*` – Sam Jan 21 '13 at 17:36
  • Thank you for your responses man. I now understand how things work a little bit more :) – Alexandru Calin Jan 21 '13 at 18:54
-1

I have created a sample program if this is what you want.

Include the needed headers (stdio.h, stdlib.h, math.h, string.h)

unsigned long convertToInt(char *x);

void main() {

char x[] = "ABCD";
unsigned long y = 0;

y = convertToInt(x);

printf("Numeric value = %lu\n", y);

}

unsigned long convertToInt(char *x) {

unsigned long num = 0, i, n;`
char hex_c;

for(i = 0; i< strlen(x); i++)  {

    hex_c = x[i];

    if (hex_c >= '0' && hex_c <= '9') {
    n = hex_c - '0';
    } else if (hex_c >= 'A' && hex_c <= 'F') {
    n =  10 + hex_c - 'A';
    } else if (hex_c >= 'a' && hex_c <= 'f') {
    n = 10 + hex_c - 'a';
    } else {
        printf("Wrong input");
    return 0;
    }

    num += n * (pow(16, (strlen(x) - i - 1)));
}

return num;

}
  • 2
    This is not about converting hexadecimal numbers, this is about getting a numeric representation of characters. 'A' needs to become 65, not 10, and "AB" would be (65*256)+66 – Maciej Stachowski Jan 21 '13 at 15:45