【问题标题】:C++ hex format stringC++ 十六进制格式字符串
【发布时间】:2020-03-26 18:25:54
【问题描述】:

Create 方法应该生成一个由 9 个字符组成的字符串,其组成如下: som 后跟 id 字符加 4 个字符(表示 value 的十六进制字符串)加上 2 个字符(表示 crc 的十六进制字符串)加上 eom 字符。 这是代码:

private: 
     char som = '$';
     char eom = '&';
     bool crc = true;

unsigned char checksum(string data) {
    unsigned char sum = 0x00;

    for (char &c : data)
        sum += c;

    return sum;
}

string epilogue(string data) {
    ostringstream _message;

    if (crc) {
        byte _sum = checksum(data);
        _message << std::hex << (_sum & 0xFF);
    }

    _message << eom;

    return _message.str();
}

string Create(char id, short value) {
    ostringstream _message, _data;

    _data << std::hex << (value & 0xFFFF);

    _message << som << id << _data.str() << epilogue(_data.str());

    return _message.str();
}

问题出在这一行:

_data << std::hex << (value & 0xFFFF);

正确输出一个十六进制字符串,但不是 正确 长度。 类似的问题应该在这一行:

_message << std::hex << (_sum & 0xFF);

如何修复此代码以准确生成我需要的模式? 在 Java 中,我使用的是这样的东西:

String.format("%02X", value & 0xFFFF)

编辑(可运行代码):

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>

using namespace std;

typedef unsigned char byte;

class PacketBuilder {
private: 
    char som = '$';
    char eom = '&';
    bool crc = true;

public:
    PacketBuilder(const char som, const char eom, bool crc) {
        this->som = som;
        this->eom = eom;
        this->crc = crc;
    }

    byte checksum(string data) {
        byte sum = 0x00;

        for (char &c : data)
            sum += c;

        return sum;
    }

    string epilogue(string data) {
        ostringstream _message;

        if (crc) {
            byte _sum = checksum(data);
            _message << std::hex << (_sum & 0xFF);
        }

        _message << eom;

        return _message.str();
    }

    string Create(char id, short value) {
        ostringstream _message, _data;

        _data << std::hex << (value & 0xFFFF);

        _message << som << id << _data.str() << epilogue(_data.str());

        return _message.str();
    }
};

int main() {
    PacketBuilder* _pb = new PacketBuilder('$','&',true);

    string _packet = _pb->Create('C',0);

    cout << _packet;

    return 0;
}

Online code

预期结果是:

$C0000c0&

【问题讨论】:

  • private char som = '$'; 不是有效的 c++,这是拼写错误还是不是 c++?
  • 我个人会使用sprintf,这将类似于 Java 解决方案。但是,如果您想以 C++ 方式执行此操作,请使用 std::setwstd::setfill 将您的输出左填充零。
  • @idclev463035818 是的,它是从错误的来源剪切和粘贴的(我正在从 Java 转换它)我现在修复了它。
  • 在任何情况下,您都应该发布minimal reproducible example 以及预期和期望的输出

标签: c++ formatting hex


【解决方案1】:

在 C++ 中使用 std::setwstd::setfill

记得保存和恢复 iomanip 标志。

string epilogue(string data) {
    ostringstream _message;

    if (crc) {
        byte _sum = checksum(data);
        const auto save = _message.flags();
        _message << std::hex << std::setw(2) 
            << std::setfill('0') << (_sum & 0xFF);
        _message.flags(save);
    }

    _message << eom;

    return _message.str();
}

string Create(char id, short value) {
    ostringstream _message, _data;

    const auto save = _data.flags();
    _data << std::hex << std::setw(4) 
            << std::setfill('0') << (value & 0xFFFF);
        _message.flags(save);

    _message << som << id << _data.str() << epilogue(_data.str());

    return _message.str();
}

format("%02X",
           ^ std::hex << std::uppercase
          ^ std::setw(2)
         ^ std::setfill('0')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-15
    • 2011-05-04
    • 2022-07-08
    • 2018-01-31
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多