0

I have created a function to count the byte length of an incoming hex string, then convert that length into hexidecimal. It first assigns the Byte Length of the incoming string to an int, then I convert the int to a string. After assigning the byte length of my incoming string to an int, I check to see if it is more than 255, if it is, I insert a zero so that I have 2 bytes returned, instead of 3-bits.

I do the follwing:

1) Takes in the Hex string and divides the number by 2.

static int ByteLen(std::string sHexStr)
{
    return (sHexStr.length() / 2);
}

2) Takes in Hex string, then converts to a Hex format string with itoa()

static std::string ByteLenStr(std::string sHexStr)
{
    //Assign the length to an int 
    int iLen = ByteLen(sHexStr);
    std::string sTemp = "";
    std::string sZero = "0";
    std::string sLen = "";
    char buffer [1000];

     if (iLen > 255)
     {
        //returns the number passed converted to hex base-16 
        //if it is over 255 then it will insert a 0 infront 
                //so to have 2 bytes instead of 3-bits
        sTemp = itoa (iLen,buffer,16);
        sLen = sTemp.insert(0,sZero);               
                return sLen;
     }

     else{
                return itoa (iLen,buffer,16);
     }
}

I convert the length to hexidecimal. This seems to work fine, however I am looking for maybe a more simpler way to format the text like I would in C# with the ToString("X2") method. Is this it for C++ or does my method work well enough?

Here is how I would do it in C#:

public static int ByteLen(string sHexStr)
        {
            return (sHexStr.Length / 2);
        }

        public static string ByteLenStr(string sHexStr)
        {
            int iLen = ByteLen(sHexStr);

            if (iLen > 255)
                return iLen.ToString("X4");
            else
                return iLen.ToString("X2");
        }

My logic may be off a bit in C++, but the C# method is good enough for me in what I want to do.

Thank you for your time.

user2577497
  • 497
  • 9
  • 17

2 Answers2

1
static std::string ByteLenStr(std::string& sHexStr)
{
    int iLen = ByteLen(sHexStr);
    char buffer[16];
    snprintf(buffer, sizeof(buffer), (iLen > 255) ? "%04x" : "%02x", iLen);
    return buffer;
}

snprintf formats text in a buffer using a format string and a variable list of arguments. We are using the %x format code to convert a int argument into a hex string. In this instance, we have two format strings to choose from:

  • When iLen > 255, we want the number to be four digits long. %04x means format as a hex string, with zero-padding at the beginning up to four places.
  • Otherwise, we want the number to be two digits long. %02x means format as a hex string, with zero-padding up to two places.

We use the ternary operator to select which format string we use. Finally, iLen is passed as the single argument which will be used to provide the value that is formatted by the function.

Jonathan Potter
  • 36,172
  • 4
  • 64
  • 79
  • Amazing...Thank you for this. Mind walking me through with all of the sytax for this line: snprintf(buffer, sizeof(buffer), (iLen > 255) ? "%04lx" : "%02lx", iLen); – user2577497 Jul 31 '13 at 21:53
  • 1
    Added some detail to the answer. – Jonathan Potter Jul 31 '13 at 22:12
  • 1
    You probably don't want to use `%04lx` when `iLen` is an int - unless long and int are the same size (and since they aren't ALWAYS the same size, it's a bad idea to use it that way, even when they are) – Mats Petersson Aug 01 '13 at 00:24
  • Great thank you for this everyone. I do have one last remark, If I am not using C++11 and are using Visual C++ 2010 Express, can I use the library for "snprintf"? Because i see from [Here](http://www.cplusplus.com/reference/cstdio/) that I am only able to use this function if I have C++11. My compiler says that it is undefined, however "sprintf" has no errors, letting me believe that this is the case and that I will need a work around. Can I use "sprintf" and not have size_t (maximum bytes used in buffer) as a param? – user2577497 Aug 01 '13 at 14:33
  • Ok I have done some research and according to [Here](http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010) I can use the first answers option. There seems to be much discussion on the usage, however it is the top answer. Will it be sufficient? – user2577497 Aug 01 '13 at 14:50
  • You can use `sprintf` really, it's "unsafe" because the buffer size isn't specified but since we know how big the string is going to be it's not an issue in this case. – Jonathan Potter Aug 01 '13 at 19:22
1

For a purely C++ solutuon that does not use any C functions, try using a std::stringstream to help you with formatting:

static std::string ByteLenStr(std::string sHexStr)
{
    //Assign the length to an int 
    int iLen = ByteLen(sHexStr);

    //return the number converted to hex base-16 
    //if it is over 255 then insert a 0 in front 
    //so to have 2 bytes instead of 3-bits

    std::stringstream ss;

    ss.fill('0');
    ss.width((iLen > 255) ? 4 : 2);
    ss << std::right << std::hex << iLen;

    return ss.str();
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770