C++11 std::snprintf

一 C

在C中,snprintf在C99中定义,头文件<stdio.h>如下:

int snprintf( char *restrict buffer, int bufsz, const char *restrict format, ... );(C99起)

其中 restrict是c99标准引入的,它只可以用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式.即它告诉编译器,所有修改该指针所指向内存中内容的操作都必须通过该指针来修改,而不能通过其它途径(其它变量或指针)来修改。

二 C++

在C++中,snprintf从C++11引入,头文件<cstdio>,如下:

int snprintf( char* buffer, std::size_t buf_size, const char* format, ... ); (C++11 起)  

三 举例

#include <cstdio>

……
char buff[1024];
uint64_t a = 123456789;
snprintf(buff, sizeof(buff), "%d", a);
std::cout << "buff : " << buff;
// 输出 buff : 123456789
……

 四 参考

C snprintf

C++ snprintf

### 解析ARP数据包并提取字段 以下是基于 `uint8_t` 数组进行字节级操作的 C++ 实现,用于解析 ARP 数据包中的各个字段: #### 定义结构体 为了方便访问 ARP 报文的各部分,可以按照给定的格式定义一个对应的结构体。 ```cpp #include <iostream> #include <cstring> #pragma pack(push, 1) // 禁用结构体填充 struct ArpHeader { uint16_t htype; // Hardware type (e.g., Ethernet = 1) uint16_t ptype; // Protocol type (e.g., IPv4 = 0x0800) uint8_t hlen; // Hardware address length (e.g., MAC = 6) uint8_t plen; // Protocol address length (e.g., IPv4 = 4) uint16_t oper; // Operation code (1=request, 2=reply) uint8_t sha[6]; // Sender hardware address (MAC) uint8_t spa[4]; // Sender protocol address (IP) uint8_t tha[6]; // Target hardware address (MAC) uint8_t tpa[4]; // Target protocol address (IP) }; #pragma pack(pop) ``` 上述结构体严格按照提供的 ARP 头部格式定义[^2],并通过 `#pragma pack(push, 1)` 来确保没有额外的内存对齐填充。 #### 提取字段功能实现 下面是一个函数 `parseARPPacket` 的实现,它接受一个指向原始数据包的指针以及数据包长度作为参数,并从中提取所需的字段。 ```cpp void parseARPPacket(const uint8_t* packet, size_t packetSize) { if (packetSize < sizeof(ArpHeader)) { std::cerr << "Packet too small to contain an ARP header." << std::endl; return; } const ArpHeader* arpHdr = reinterpret_cast<const ArpHeader*>(packet); // Extract fields from the ARP header uint16_t hardwareType = ntohs(arpHdr->htype); // Convert network byte order to host byte order uint16_t protocolType = ntohs(arpHdr->ptype); uint8_t hardwareAddressLength = arpHdr->hlen; uint8_t protocolAddressLength = arpHdr->plen; uint16_t operationCode = ntohs(arpHdr->oper); char senderMacStr[18]; snprintf(senderMacStr, sizeof(senderMacStr), "%02X:%02X:%02X:%02X:%02X:%02X", arpHdr->sha[0], arpHdr->sha[1], arpHdr->sha[2], arpHdr->sha[3], arpHdr->sha[4], arpHdr->sha[5]); char senderIpStr[16]; snprintf(senderIpStr, sizeof(senderIpStr), "%u.%u.%u.%u", arpHdr->spa[0], arpHdr->spa[1], arpHdr->spa[2], arpHdr->spa[3]); char targetMacStr[18]; snprintf(targetMacStr, sizeof(targetMacStr), "%02X:%02X:%02X:%02X:%02X:%02X", arpHdr->tha[0], arpHdr->tha[1], arpHdr->tha[2], arpHdr->tha[3], arpHdr->tha[4], arpHdr->tha[5]); char targetIpStr[16]; snprintf(targetIpStr, sizeof(targetIpStr), "%u.%u.%u.%u", arpHdr->tpa[0], arpHdr->tpa[1], arpHdr->tpa[2], arpHdr->tpa[3]); // Output extracted information std::cout << "Hardware Type: " << hardwareType << std::endl; std::cout << "Protocol Type: 0x" << std::hex << protocolType << std::dec << std::endl; std::cout << "Hardware Address Length: " << static_cast<int>(hardwareAddressLength) << std::endl; std::cout << "Protocol Address Length: " << static_cast<int>(protocolAddressLength) << std::endl; std::cout << "Operation Code: " << operationCode << std::endl; std::cout << "Sender MAC Address: " << senderMacStr << std::endl; std::cout << "Sender IP Address: " << senderIpStr << std::endl; std::cout << "Target MAC Address: " << targetMacStr << std::endl; std::cout << "Target IP Address: " << targetIpStr << std::endl; } ``` 此代码片段实现了从 `uint8_t` 数组中读取 ARP 数据包的功能,并将其转换为人可读的形式输出。注意使用了 `ntohs()` 函数来处理网络字节序到主机字节序的转换。 #### 使用示例 假设我们已经通过某种方式捕获了一个完整的 ARP 数据包存储在一个缓冲区中,则可以通过调用该函数来进行分析。 ```cpp int main() { // Example buffer containing a raw ARP packet data. uint8_t exampleArpPacket[] = { 0x00, 0x01, // Hardware type (Ethernet) 0x08, 0x00, // Protocol type (IPv4) 0x06, // Hardware address length (MAC is 6 bytes) 0x04, // Protocol address length (IPv4 is 4 bytes) 0x00, 0x01, // Operation code (ARP request) 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, // Sender MAC address 0xc0, 0xa8, 0x01, 0x01, // Sender IP address 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Target MAC address (all zeros for requests) 0xc0, 0xa8, 0x01, 0x02 // Target IP address }; parseARPPacket(exampleArpPacket, sizeof(exampleArpPacket)); return 0; } ``` 以上展示了如何创建测试环境下的模拟 ARP 数据包及其解析过程。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值