-1

How can I convert from char * to int to hex decimal? My input is 78 and I expect 4e but get 3465 as result.

int main()
{
  char *input = "78";
  int num = strtol(input, NULL, 10); // to int
  char out[2];
  sprintf(out, "%x", num); // to hex
  for(int i=0;i<2;i++)
    printf("%x\n", out[i]);
}
Sam
  • 387
  • 2
  • 9
  • 22
  • 1
    You should be using `%c` in your `printf`. Or just print your `out` as a string with `%s` in one instruction, not in a loop (but in that case, don't forget to add a NULL terminator, so need to increase array size by 1). – AntonH Aug 22 '17 at 15:18
  • `printf("%s\n", out);`. And you need to make your `out` bigger. `sprintf` is overflowing it with `\0`. – Eugene Sh. Aug 22 '17 at 15:19
  • Function `printf` is not really important in this case, I use it to proof weather `out` contains `4e`. Making `out` bigger does not solve my problem. – Sam Aug 22 '17 at 15:22
  • 1
    It is important, as that's where your issue is. `out` is holding the value after the 2 transformations (char * to int, int to hex), so `out` contains what you're expecting, i.e. "4e". But you're printing the hex values of those characters. You have the right answer, just displaying it wrong. – AntonH Aug 22 '17 at 15:24
  • 1
    So your "proof" is wrong and not showing what it is supposed to show. Before you are using a tool to prove something, you should show your tool is working. – Eugene Sh. Aug 22 '17 at 15:25
  • @haccks not sure about this duplicate because, although the *goal* is the same, this here is a *why doesn't this code work*-question ... –  Aug 22 '17 at 15:28
  • @FelixPalmen While I agree that it shouldn't have been closed as duplicate (because of reasons you stated), I do think it should have been closed. The code is working (almost, as you did say that `out` should be one byte longer for NULL terminator), but the issue is OP is displaying the hex values of the hex characters, and not the hex characters themselves. – AntonH Aug 22 '17 at 15:32
  • @AntonH I don't see a matching close reason for that. Although this "*double hexing*" is quite peculiar, it's not unclear, not too broad, and beyond a "simple typo" ... :o (and the question contains MCVE as well) –  Aug 22 '17 at 15:33
  • @FelixPalmen I was thinking of the "typographical" (replace %x with %c in printf), although I do admit it is a bit of a stretch. Or "code not working ...", simply because the code *is* working. – AntonH Aug 22 '17 at 15:35
  • 1
    @AntonH hmm `%c` for `%x` **would** work here when also using `snprintf()` instead of `sprintf()`. So, maybe that's enough for *typo*, but yes, it's a bit of a stretch. Because of this rather strange error, I bet you don't find a **good** duplicate as well. Leaving it closed because I *feel* it shouldn't be reopened, but really unsure about the reasoning... –  Aug 22 '17 at 15:40

1 Answers1

3

This is wrong:

char out[2];
sprintf(out, "%x", num); // to hex

because you write beyond the bounds of the array. Your number has two hexadecimal places, and you need an additional byte for the \0 terminator of the string. It has to be at least char out[3].

This is even wronger:

for(int i=0;i<2;i++)
  printf("%x\n", out[i]);

You already have a hexadecimal string representation of the number and now take the individual characters and interpret them as hexadecimal numbers. Just output your out string instead, e.g. puts(out) or printf("%s\n", out) (requires the \0 terminator to be present).

You can condense the whole thing to just

int main(void)
{
  char *input = "78";
  long num = strtol(input, NULL, 10); // to int
  printf("%lx\n", num); // to hex
}

(note that strtol() returns long -- with larger numbers you'd get a problem converting this to int.)

  • and how can I store the result which is printed in a char * or char[] ? – Sam Aug 22 '17 at 15:32
  • 1
    You already do that with your `sprintf()`? The only problem there is the array was one too small, as I wrote. –  Aug 22 '17 at 15:34