【问题标题】:Alternate way to get the Byte Length of a Hex string获取十六进制字符串的字节长度的替代方法
【发布时间】:2013-08-01 14:39:37
【问题描述】:

我创建了一个函数来计算传入十六进制字符串的字节长度,然后将该长度转换为十六进制。它首先将传入字符串的字节长度分配给一个 int,然后我将 int 转换为一个字符串。将传入字符串的字节长度分配给一个 int 后,我​​检查它是否超过 255,如果是,我插入一个零,以便返回 2 个字节,而不是 3 位。

我执行以下操作:

1) 接受十六进制字符串并将数字除以2。

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

2) 接受十六进制字符串,然后用 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);
     }
}

我将长度转换为十六进制。这似乎工作正常,但是我正在寻找一种更简单的方法来格式化文本,就像我在 C# 中使用 ToString("X2") 方法一样。这是用于 C++ 还是我的方法足够好?

这是我在 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");
        }

我的逻辑在 C++ 中可能有点偏离,但 C# 方法对我想做的事情来说已经足够好了。

感谢您的宝贵时间。

【问题讨论】:

    标签: c++ visual-studio-2010 visual-c++ unmanaged


    【解决方案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 使用格式字符串和变量参数列表格式化缓冲区中的文本。我们正在使用 %x 格式代码将 int 参数转换为十六进制字符串。在本例中,我们有两种格式字符串可供选择:

    • iLen > 255 时,我们希望数字长度为四位数。 %04x 表示格式为十六进制字符串,在开头最多四个位置补零。
    • 否则,我们希望数字长度为两位数。 %02x 表示格式为十六进制字符串,最多两个位置补零。

    我们使用ternary operator 来选择我们使用的格式字符串。最后,iLen 作为单个参数传递,该参数将用于提供由函数格式化的值。

    【讨论】:

    • 太棒了...谢谢你。介意带我了解这一行的所有语法:snprintf(buffer, sizeof(buffer), (iLen > 255) ? "%04lx" : "%02lx", iLen);
    • 在答案中添加了一些细节。
    • iLen 是 int 时,您可能不想使用 %04lx - 除非 long 和 int 的大小相同(而且由于它们的大小并不总是相同,这很糟糕想法以这种方式使用它,即使它们是)
    • 非常感谢大家。我有最后一句话,如果我不使用 C++11 而是使用 Visual C++ 2010 Express,我可以将库用于“snprintf”吗?因为我从Here 看到,如果我有 C++11,我只能使用这个函数。我的编译器说它是未定义的,但是“sprintf”没有错误,让我相信情况就是这样,我需要解决这个问题。我可以使用“sprintf”并且没有 size_t(缓冲区中使用的最大字节数)作为参数吗?
    • 好的,我已经做了一些研究,根据Here,我可以使用第一个答案选项。关于用法似乎有很多讨论,但这是最佳答案。够用吗?
    【解决方案2】:

    对于不使用任何 C 函数的纯 C++ 解决方案,请尝试使用std::stringstream 来帮助您进行格式化:

    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();
    }
    

    【讨论】:

      猜你喜欢
      • 2019-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-24
      • 1970-01-01
      • 2016-10-05
      • 2016-05-22
      • 2012-06-13
      相关资源
      最近更新 更多