954,483 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

unsigned character pointer to Hex values

Dear all:

I've created TCPsocket in linux using C++. It receives an array of unsigned characters. I need the corresponding hex values in character format.
i.e. "ABC" in hex it is "414243". Now I want to treat each of "414243" as character.

So I have done the coding as follow ( taking into cosideration that the TCP socket is established and the data is received in an unsigned character pointer m_cpSockData sized same to Buffer Size of the socket. And the number of byte read is m_iReadLen).

char* m_cHexvalue = new char[2*BufSize +1];
char *m_cCurrCharVal=new char[3];

*(m_cCurrCharVal+2)=0X00;
memset(m_cHexvalue ,0,2);

for(int count=0;count<BufSize ;count++)
{
     memset(m_cCurrCharVal,0,2);
     sprintf(m_cCurrCharVal,"%x",*(m_cpSockData+count));
     strcat(m_cHexvalue ,m_cCurrCharVal);

}


<< moderator edit: added [code][/code] tags >>


I also have similar thing while writing back to the socket.

But this reduces the efficiency of the code..

Can any body help to provide a mechanism where efficiency can be increased.

Sutanu
Newbie Poster
10 posts since Aug 2005
Reputation Points: 10
Solved Threads: 0
 

This is pretty much the same, but it's all I've got at the moment.

#include <stdio.h>

char *foo(char *dst, const char *src)
{
   char *start = dst;
   while ( *src )
   {
      dst += sprintf(dst, "%x", (unsigned)*src++);
   }
   return start;
}

char *bar(char *dst, const char *src)
{
   char *start = dst;
   while ( *src )
   {
      unsigned value;
      if ( sscanf(src, "%2x", &value) == 1 )
      {
         src += 2;
         *dst++ = value;
      }
   }
   *dst = '\0';
   return start;
}

int main(void)
{
   const char abc[] = "ABC";
   char over [ sizeof abc * 2  - 1 ], back [ sizeof abc ];
   printf("\"%s\" -> \"%s\"\n", abc,  foo(over, abc));
   printf("\"%s\" -> \"%s\"\n", over, bar(back, over));
   return 0;
}

/* my output
"ABC" -> "414243"
"414243" -> "ABC"
*/
Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

Thanks for the reply.

I understand you have removed some operations. That reduces quite a big time.

I think this can further be minimized. Do you have any idea of doing this with the help of asm codes in C.

I've not used so far but I think that may help the roundtrip time.

Thanks again.
Sutanu

Sutanu
Newbie Poster
10 posts since Aug 2005
Reputation Points: 10
Solved Threads: 0
 

Perhaps discard the standard routines and roll your own.

#include <stdio.h>
#include <ctype.h>

unsigned char *foo(unsigned char *dst, const unsigned char *src)
{
   static const unsigned char nibble[] = 
   {
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
   };
   unsigned char *start = dst;
   while ( *src )
   {
      *dst++ = nibble [ *src >> 4    ];
      *dst++ = nibble [ *src++ & 0xF ];
   }
   *dst = '\0';
   return start;
}

unsigned char *bar(unsigned char *dst, const unsigned char *src)
{
   unsigned char *start = dst;
   while ( *src )
   {
      if ( isdigit(*src) )
      {
         *dst = *src++ - '0';
      }
      else
      {
         *dst = *src++ - 'A' + 10;
      }
      *dst <<= 4;
      if ( isdigit(*src) )
      {
         *dst++ += *src++ - '0';
      }
      else
      {
         *dst++ += *src++ - 'A' + 10;
      }
   }
   *dst = '\0';
   return start;
}

int main(void)
{
   const unsigned char abc[] = "ABCMNO";
   unsigned char over [ sizeof abc * 2  - 1 ], back [ sizeof abc ];
   printf("\"%s\" -> \"%s\"\n", abc,  foo(over, abc));
   printf("\"%s\" -> \"%s\"\n", over, bar(back, over));
   return 0;
}

/* my output
"ABCMNO" -> "4142434D4E4F"
"4142434D4E4F" -> "ABCMNO"
*/


This is for ASCII, and I think it is right. But I was wrong with it a minute ago.

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

Thanks again.

I performed a dry run. I think it would be better to use

if (*src <= '9')

rather than

if (isdigit(*src))

What do you think...

Sutanu

Sutanu
Newbie Poster
10 posts since Aug 2005
Reputation Points: 10
Solved Threads: 0
 

I performed a dry run. I think it would be better to use

if (*src <= '9')

rather than

if (isdigit(*src))

What do you think...

Sutanu

If that works better, go ahead. Many times the standard functions are implemented faster than writing an equivalent, but not always.

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 
if( *src <= '9' )


what if *src < '0' ? isdigit() will catch that, but your if statement won't.

Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 

Thanks for the concern.

The scenario I'm talking about doesn't permit you to have any values other than 0-9 and A-F.

In other scenarios or to have a generic one I think using a isdigit() is a better option. But then also you can see what happens if any character as * ( ASCII value is 42) comes . Then you probably will have a negative value (42 - 64 +10 = -12).

Sutanu
Newbie Poster
10 posts since Aug 2005
Reputation Points: 10
Solved Threads: 0
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You