【问题标题】:append IP address to char* using C++使用 C++ 将 IP 地址附加到 char*
【发布时间】:2019-01-16 16:51:12
【问题描述】:

我是 C++ 新手。我想将IP address 附加到已经存在的char*

谁能告诉我怎么做。 提前致谢

【问题讨论】:

  • 答案是...... 你不会在 C++ 中这样做 你使用 char* 代替 std::string 进行字符串操作。在处理第三方库和 C 代码时,C 风格的字符串 (char*) 有时是必不可少的。另外,不要使用#define 来定义文字。
  • 注意"\x42\x01"不是十六进制数字串;与{ 0x42, 0x01, 0x0 } 相同,与{ 66, 1, 0 } 相同。也就是说,它是一个包含这些数字的“字符串”,而不是这些数字的十六进制表示。
  • 换句话说:您不应该涉及printf 或任何其他对字符串的转换。您希望将 IP 地址分解为字节并附加那些 数字,而不是它们的文本表示。
  • 该命令的意图是什么?您是要在char* 中添加数字作为字符串,还是您实际上是要拥有二进制数据?您还想在命令中包含二进制数据(表示 IP 地址)还是想要 CIDR 格式的实际 IP 地址?
  • 在我看来,在这种情况下,您的 char * 应该更像是 char[](如果遵循 C),但我不会使用字符串在 C++ 中对其进行建模,而是使用std::vector<char>,因为您想在末尾追加。

标签: c++ arrays string append ip


【解决方案1】:

如果你使用 c++ 而不是 c,这会变得更容易。如果您使用boost::asio(即将成为标准的一部分),它会更容易。

const std::string IP = "169.254.1.34"; // don't use #define to define constants
auto address = boost::asio::ip::make_address_v4( IP );

std::stringstream command;
command << "\x42\x01\x00\x82\x00\x08\x10\x1f\x00\x00\x0d\x18";
auto decimal = htonl( address.to_uint() );
command.write( (char*)decimal, sizeof(decimal) );

【讨论】:

  • 仅仅为此链接提升似乎有点……反应过度,你不觉得吗?
  • @LeontyevGeorgiy 是的,但大概他会做其他网络工作,使用 asio 比使用原始套接字更容易。另外我认为没有链接,因为 asio 只是标题。
  • 盖伊是个菜鸟。 Boost::asio API 不适合初学者......但是,如果可以真正使用它,它肯定比原始套接字更好。我认为,对他来说,这一步太过分了。作为 5 年的 c++ 开发人员,我仍然有点害怕使用 Boost,因为我还没有准备好使用 Boost 的早期经验......
【解决方案2】:

我假设您的任务是实现某种二进制通信协议,其中涉及在命令中将 IP 地址作为 4 字节值发送。为了以正确的方式做到这一点,我将创建一个包含 IP 地址(作为无符号整数)和命令后缀的结构。这为您在构建包时提供了更大的灵活性。差不多,像这样:

template <int suffix_size>
struct Packet
{   
    uint32_t ip_binary_;
    char data_[suffix_size];

    template<int suffix_size>
    Packet<suffix_size>(std::string IP, const char* command_byte_array)
    {
        ip_binary_ = inet_addr(IP.c_str());
        memcpy(data_, command_byte_array, suffix_size);
    }

    template<int suffix_size>
    const char* pack() const
    {
        return reinterpret_cast<const char*>(this);
    }

    template<int suffix_size>
    int size() const { return suffix_size + sizeof(uint32_t); }
};

通过此示例,您可以分别定义大小和 IP 地址。另外,pack() 方法会自动打包。

(没有测试代码,可能会有一些错误,但我希望你能明白这一点)

编辑:总的来说,如果您实际上是在实施协议,请确保您的命令描述尽可能明确。使用 char* 及其偏移量将数据放在那里......它可以工作,但会使代码不可读。

从这个例子你可以扩展,例如 -

struct SomeCmdPacket: Packet<SomeCmdPacketSize>
{
    ...
    SomeCmdPacket(std::string IP):
    Packet<SomeCmdPacketSize>(IP, "\x00*put your command here*");
    {

    }
};

【讨论】:

    猜你喜欢
    • 2012-10-08
    • 2022-10-19
    • 2015-10-07
    • 2012-07-05
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-27
    相关资源
    最近更新 更多