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.

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"
*/

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

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.

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

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.

if( *src <= '9' )

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

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).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.