![]() |
| |||||||
![]() |
| | LinkBack | Thread Tools | Display Modes |
| | #1 |
| Registered User Join Date: Mar 2006 Location: dedham, MA
Posts: 10
| No atoh() function in C ( Ascii To Hex )? - Well, Let's Create One My goal is to have the user enter a Hex depicted input ( ie. "ff0077554433" ) which of course gets interpreted as ascii characters, and then convert the hex depicted ascii characters to actual hex values. Therefore, upon the user entering "ff00775533", after the conversion over to hex, I'd should have a character string in my program that contains the following values: UserInput[0]=0xff UserInput[1]=0x00 UserInput[2]=0x77 UserInput[3]=0x55 UserInput[4]=0x44 UserInput[5]=0x33 One may so, "Oh, well that's easy!". However, after reading various C references as well as searching over the Internet to find code that does this, the only code that I've found so far that works is as follows: Code:
unsigned long int UserInput = 0;
int main()
{
/* Get user HEX input */
Printf ( "Please enter hex value\n");
scanf("%x", &UserInput );
/* User then input's something like "ff008877" */
printf("The converted hex text decimal value is now %d",
UserInput );
return 0;
}
Code: The converted hex text decimal value is now 4278225015 And so this works fine. The conversion is made from the ascii hex input to actual hex values as confirmed by the decimal output. However, the problem here is that the user is limited to an input of only 4 HEX BYTES. I REALLY WISH there were a function that took an input such as: ff008877663344 - ( Ascii Input of course ) and returned a string with each byte containing the following values: OutPutString[0] = 0xff OutPutString[1] = 0x00 OutPutString[2] = 0x88 OutPutString[3] = 0x77 OutPutString[4] = 0x66 OutPutString[5] = 0x33 OutPutString[6] = 0x44 Such a function would logically be called atoh ( Ascii to Hex ) and have the following signature: Code: int atoh(char*, char*) Therefore, in trying to create my own version of atoh( char*, char* ) I've written the following program. Please note that for now, instead of implementing this code inside of a function called int atoh(char *, char* ), for testing purposes, the code is contained in a main() program for now. Code:
#include <stdio.h>
#include <string.h>
union IntCharUnion
{
unsigned long int UserInputInt;
char UserInputChar[4];
};
int main()
{
/* Union Containing an integer and char of 4 bytes */
IntCharUnion IntCharVar;
/* Used to reference each element of user input */
int InputIndex = 0;
/* String that captures user input of up to 12 chars. Could
make it larger, but let's keep it simple for now. */
char UserInput[12] = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0' };
/* The resulting string containing the Converted Ascii --->
Hex Chars. */
char OutputBuffOfHex[7];
/* Used to temporarily store 4 hex values that ultimately get
appended to the output string */
char PreConversionBuff[4];
printf ( "Please enter hex value\n");
scanf("%s", UserInput );
/* At this point, user then input's something like "ff008877554422" */
/* Set up loops that peform the conversion to actual hex */
while( UserInput[InputIndex] != '0' )
{
/* Every 4 bytes, convert the latest 4 bytes from ascii to hex via.
the %x specifier. We can only do this 4 bytes at a time using the
%x specifier. */
if( ( InputIndex != 0) && ( ( InputIndex % 4 ) == 0 ) )
{
/* Perform the conversion for this grouping of 4 bytes */
sscanf( PreConversionBuff, "%x",
&IntCharVar.UserInputInt );
/* And Now, append the new Hex values inside of the Union
to the output string */
strcat( OutputBuffOfHex, IntCharVar.UserInputChar);
InputIndex++;
}
/* Else, transfer this byte to the buffer. */
else
{
PreConversionBuff[InputIndex] = UserInput[InputIndex];
InputIndex++;
}
/* end if */
}/* end while */
printf("\nThe value of the OutputBuffOfHex is %x\n", OutputBuffOfHex );
}
Program output: Code: Please enter hex value 1122 The value of the OutputBuffOfHex is ffbef301 After investingating this closely, the problem appears to be in using the union. That is, after the following line of code gets executed: Code: /* Perform the conversion for this grouping of 4 bytes */
sscanf( PreConversionBuff, "%x",
&IntCharVar.UserInputInt );
So, then, I wrote a smaller program to see how I could get the union to work the way I wanted. The program is as follows: Code:
union IntCharUnion
{
unsigned long int UserInputInt;
char UserInputChar[4];
};
int main()
{
IntCharUnion IntCharVar;
Printf ( "Please enter hex value\n");
scanf("%x", &IntToStringOfHex.UserInputInt );
/* User then input's something like "ff008877" */
/* Then, just as a sanity check, print out what's in the Char
String portion of the UnionVar */
printf( "Hex values now stored in the char string portion of
the Union are as follows: %x", IntToStringOfHex.
UserInputChar );
return 0;
}
Code: Please enter hex value ff008877 Hex values now stored in the char string portion of the Union are as follows: ffbef316 Of course the desired result is: Code: Hex values now stored in the char string portion of the Union are as follows: ff008877 Code:
#include <stdio.h>
#include <string.h>
int main()
{
char UserInput[10];
char DestinationBuffer[4];
int intBuff = 0;
DestinationBuffer[0] = 0;
DestinationBuffer[1] = 0;
DestinationBuffer[2] = 0;
DestinationBuffer[3] = 0;
/* Get the entire ascii hex digit input and store into a char array */
printf("Please enter the the hex packet of data\n", UserInput );
scanf("%s", UserInput );
/* Convert the ascii input to Hex via. the "%x" specifier */
sscanf(UserInput, "%x", &intBuff );
printf ("The int value is now %d\n", intBuff);
/* And finally, move the 4 byte hex value from the integer to
the desired output string. */
memmove( DestinationBuffer, &intBuff, 4);
printf("%x\n", DestinationBuffer );
return 0;
}
Program output: Code: Please enter the the hex packet of data 1122 The int value is now 4386 ffbef316 Again, the conversion from ascii hex depicted input to hex actual hex worked: Code: /* Convert the ascii input to Hex via. the "%x" specifier */
sscanf(UserInput, "%x", &intBuff );
printf ("The int value is now %d\n", intBuff);
Code: * And finally, move the 4 byte hex value from the integer to
the desired output string. */
memmove( DestinationBuffer, &intBuff, 4);
printf("%x\n", DestinationBuffer );
Thanks in advance, dedham_ma_man Last edited by dedham_ma_man; 03-18-2006 at 12:58 PM. |
| dedham_ma_man is offline | |
| | #2 |
| +++ OK NO CARRIER Join Date: Oct 2001
Posts: 10,260
| All you really need is to convert each 2 characters entered into a single character, and to display each character in your new array as its decimal value. You can't treat the second array as a string, in case they enter 00. Quzah.
__________________ Hundreds of thousands of dipshits can't be wrong. Are you up for the suck? |
| quzah is offline | |
| | #3 |
| and the hat of vanishing Join Date: Aug 2001 Location: The edge of the known universe
Posts: 21,214
| Like this? Code: #include <stdio.h>
int main ( ) {
char buffer[] = "ff008877554422\n";
int res, pos = 0;
unsigned int byte;
printf( "Scanning %s", buffer );
while ( (res=sscanf( &buffer[pos], "%2x", &byte )) == 1 ) {
printf( "res=%d, byte=%d(%02x)\n", res, byte, byte );
pos += 2;
}
return 0;
}
__________________ If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut. Up to 8Mb PlusNet broadband from only £5.99 a month! |
| Salem is offline | |
| | #4 | |
| Just Lurking Join Date: Oct 2002
Posts: 4,990
| Sorry, long post, I only skimmed after a bit. Quote:
Code: #include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main( void )
{
char input[] = "ff008877663344", *ptr = input;
unsigned int byte;
unsigned char array[8];
size_t i, j;
for ( i = 0; i < sizeof array; ++i )
{
if ( sscanf(ptr, "%2x", &byte) != 1 )
{
break;
}
array[i] = byte;
ptr += 2;
}
for ( j = i, i = 0; i < j; ++i )
{
printf("array[%lu] = %02X\n", (long unsigned)i, (unsigned)array[i]);
}
return 0;
}
/* my output
array[0] = FF
array[1] = 00
array[2] = 88
array[3] = 77
array[4] = 66
array[5] = 33
array[6] = 44
*/
__________________ 7. It is easier to write an incorrect program than understand a correct one. 40. There are two ways to write error-free programs; only the third one works.* Last edited by Dave_Sinkula; 03-18-2006 at 01:29 PM. Reason: D'oh! Pokey again. :( | |
| Dave_Sinkula is offline | |
| | #5 |
| Guest Join Date: Aug 2001
Posts: 4,923
| I can't argue that this is simpler than what's already been suggested, but it's probably faster with larger strings: Code: char *
atohx(char * dst, const char * src)
{
char
* ret = dst;
for(int lsb, msb; *src; src += 2)
{
msb = tolower(*src);
lsb = tolower(*(src + 1));
msb -= isdigit(msb) ? 0x30 : 0x57;
lsb -= isdigit(lsb) ? 0x30 : 0x57;
if((msb < 0x0 || msb > 0xf) || (lsb < 0x0 || lsb > 0xf))
{
*ret = 0;
return NULL;
}
*dst++ = (char)(lsb | (msb << 4));
}
*dst = 0;
return ret;
}
|
| Sebastiani is offline | |
| | #6 |
| Registered User Join Date: Mar 2006 Location: dedham, MA
Posts: 10
| Thanks all - this has helped tremendously - ie. converting from Ascii depicted Hex to char string. As mentioned in the second part of this long post of mine, how would one go from a 4byte char string back to an int. In other words, if I have: CharString[0] = 0x00 CharString[1] = 0x88 CharString[2] = 0x00 CharString[3] = 0x00 and want to move those 4 bytes into an Integer, how would I do that? Among other things, I've tried the following: Code:
char BitBuffer[4] = { 0x00, 0x88, 0x00, 0x00 };
int IntBits = 0;
unsigned int byte = 0;
//printf( "The value of BitBuffer is %2x\n", BitBuffer[1]);
sscanf(BitBuffer, "%d", &IntBits );
printf("\nThe integer value of IntBits is %d\n", IntBits );
Code: The integer value of IntBits is 0 |
| dedham_ma_man is offline | |
| | #7 |
| Just Lurking Join Date: Oct 2002
Posts: 4,990
| Is this the output you expect? Code: #include <stdio.h>
int main( void )
{
char BitBuffer[4] = { 0x00, 0x88, 0x00, 0x00 };
int IntBits = *(int*)BitBuffer;
printf("The integer value of IntBits is %d\n", IntBits );
return 0;
}
/* my output
The integer value of IntBits is 34816
*/
__________________ 7. It is easier to write an incorrect program than understand a correct one. 40. There are two ways to write error-free programs; only the third one works.* |
| Dave_Sinkula is offline | |
| | #8 |
| Registered User Join Date: Mar 2006 Location: dedham, MA
Posts: 10
| Beautiful, thank you. |
| dedham_ma_man is offline | |
| | #9 | |
| Registered User Join Date: Mar 2006 Location: dedham, MA
Posts: 10
| Quote:
So, I've tried the following: Code:
char BitBuffer[4] = { 0x99, 0x88, 0x77, 0x00 };
unsigned int IntBits = *(unsigned int*)BitBuffer;
printf("The integer value of IntBits is %d\n", IntBits );
return 0;
So, I became desperate, I've tried this: Code:
char BitBuffer[4] = { 0x99, 0x88, 0x77, 0x00 };
unsigned long int IntBits = *(unsigned long int*)BitBuffer;
printf("The integer value of IntBits is %d\n", IntBits );
return 0;
The output should be 10061943 Any ideas what I'm missing? Thanks again | |
| dedham_ma_man is offline | |
| | #10 |
| and the hat of vanishing Join Date: Aug 2001 Location: The edge of the known universe
Posts: 21,214
| How about Code: char BitBuffer[4] = { 0x00, 0x99, 0x88, 0x77 };
Also, casting in this way is likely to get you a bus error on some machines, if the alignment doesn't match. memcpy( &IntBits, BitBuffer, sizeof IntBits ); is a much safer way
__________________ If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut. Up to 8Mb PlusNet broadband from only £5.99 a month! |
| Salem is offline | |
| | #11 | |
| Registered User Join Date: Mar 2006 Location: dedham, MA
Posts: 10
| Quote:
Last edited by dedham_ma_man; 03-24-2006 at 11:32 AM. | |
| dedham_ma_man is offline | |
| | #12 |
| Been here, done that. Join Date: May 2003
Posts: 1,036
| Another option that could do what you want: Code: union
{
unsigned int ival;
unsigned char bval[4];
} un;
__________________ There are only 10 types of people in the world -- those that use binary, and those that don't |
| WaltP is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Troubleshooting Input Function | SiliconHobo | C Programming | 14 | 12-05-2007 07:18 AM |
| We Got _DEBUG Errors | Tonto | Windows Programming | 5 | 12-22-2006 05:45 PM |
| const at the end of a sub routine? | Kleid-0 | C++ Programming | 14 | 10-23-2005 06:44 PM |
| airport Log program using 3D linked List : problem reading from file | gemini_shooter | C Programming | 3 | 03-04-2005 02:46 PM |
| How do I create 2 dimensional array in function and use outside of function ? | Cahunna54 | C Programming | 4 | 11-07-2001 02:46 PM |