Good day!

I need to translate incoming hex information into char. Unfortunately, the following code turns any incoming information into (null).

Could someone point out a mistake?

#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(void) { char in[255]; fgets(in, sizeof(in), stdin); int i = 0; char myChar; while(in[i]) { in[i++] = myChar; if(i == 2) { i = 0; myChar = strtol(in, NULL, 16); printf("%c", myChar); } } } 
  • Is this exactly the whole code? I have a suspicion that he shouldn’t get together ... - Vladimir Martyanov
  • I forgot to insert an array :) Corrected - Arden
  • Using the uninitialized variable myChar at least ... Well, in general, in the debugger, see what is happening there. - Vladimir Martyanov
  • @Arden Show with an example what the incoming line looks like, which you should get as a result. As for your code, it is meaningless. - Vlad from Moscow
  • Log in: 48656c6c6fa Logout: Hello And what exactly is meaningless there? - Arden

5 answers 5

My five kopecks. :)

True, my solution turned out to be not so compact, but it checks if a character that does not represent a hexadecimal number is encountered in the string, then it is skipped.

It converts the source string of hexadecimal digits to a string of characters that have corresponding codes composed of adjacent hexadecimal digits. That is, makes the conversion "in place".

 #include <stdio.h> #include <string.h> #include <ctype.h> #define N 266 int main( void ) { char s[N]; fgets( s, N, stdin ); s[strcspn( s, "\n")] = '\0'; char *p = s; int valid = 0; for ( char *q = s; *q; ++q ) { if ( isxdigit( ( unsigned char )*q ) ) { char c = toupper( ( unsigned char )*q ); c = isalpha( ( unsigned char )c ) ? c - 'A' + 10 : c - '0'; if ( valid ^= 1 ) { *p = c; } else { *p <<= 4; *p++ |= c; } } else { valid = 0; } } *p = '\0'; puts( s ); return 0; } 

If you enter a string

 48656c6c6f20576f726c6421 

then console output will be

 Hello World! 
  • Exactly what is needed. Thank you very much! - Arden
  • @Arden Not at all. Today you have a wide choice of solutions presented. :) - Vlad from Moscow

Well, simply and ineffectively :) - for example, like this:

 int main(int argc, const char * argv[]) { char * in = "48656c6c6f0a"; char hex[3]; int x; for(char * c = in; *c; ++c) { hex[0] = *c++; hex[1] = *c; hex[2] = 0; sscanf(hex,"%x",&x); printf("%c",x); } } 

We take two characters from the incoming string, scan it as a hexadecimal value, print it as char ...

Or even shorter:

 int main(int argc, const char * argv[]) { char * in = "48656c6c6f0a"; int x; for(; *in; in+=2) { sscanf(in,"%2x",&x); printf("%c",x); } } 

Without sscanf :

 int toInt(char c) { if ((c >= '0') && (c <= '9')) return c-'0'; if ((c >= 'a') && (c <= 'f')) return c-'a'+10; if ((c >= 'A') && (c <= 'F')) return c-'A'+10; printf("Wrong symbol!\n"); exit(1); } int main(int argc, const char * argv[]) { char * in = "48656c6c6f0a"; int x; for(; *in; in+=2) { x = toInt(*in)*16+toInt(*(in+1)); printf("%c",x); } } 
  • Thank you, but unfortunately I can’t use scanf. - Arden
  • Strongly more effective something is not thought out. Only to write the function for caste a character in int. - Qwertiy
  • @Arden Well, here you are without him ... (See the amended answer) - Harry
 #include <iostream> using namespace std; int main() { int a = 0x48; int b = 0x45; int c = 0x4C; int d = 0x4C; int f = 0x4F; char h; char e; char l_zero; char l_uno; char o; h = a; e = b; l_zero = c; l_uno = d; o = f; cout << h << e << l_zero << l_uno << o << endl; return 0; } 
  • one
    Alas, in C cout not provided ... - Harry

http://ideone.com/PUB59P

 #include <stdio.h> int main(void) { const char *in= "4A75737420612074657374"; unsigned q; int ch; for (q=0; in[q]; q+=2) { sscanf(in+q, "%2X", &ch); printf("%c", ch); } return 0; } 

    Option without scanf: http://ideone.com/oKqhFg

     #include <stdio.h> int digit(char ch) { return ch - (ch<='9' ? '0': ch<='Z' ? 'A'-10 : 'a'-10); } int main(void) { const char *in= "4A75737420612074657374"; unsigned q; for (q=0; in[q]; q+=2) printf("%c", (digit(in[q])<<4) | digit(in[q+1])); return 0; } 
    • Requires keyboard output. When using fgets, displays 0 - Arden
    • @Arden, so use gets . - Qwertiy
    • And 0, it still does not display. - Qwertiy