将二进制十六进制数据转换为等效的 ASCII 并存储在字符串中
Convert binary hex data to ASCII equivalent and store in String
我在 Arduino 上使用 C++。
假设我有一个二进制数据流;
二进制数据:0xFF, 0x00, 0x01, 0xCC
我想将其转换为等效的 ASCII 并将其存储在 String 对象类型中。
转换后的字符串应如下所示 "FF0001CC"。
这是一些代码草稿。
char buffer[100];
String myString;
for (int i=0; i < numBytes; i++)
{
//assume buffer contains some binary data at this point
myString += String(buffer[i], HEX);
}
此代码的问题是 myString
包含 FF01CC
,而不是 FF0001CC
。
我的猜测是每次附加文本时字符串 class 都会调整大小,这可以改进。
假设您知道输入大小并且它是常数,您可以试试这个:
char outbuffer[numBytes*2+1];
const char* pHexTable="0123456789ABCDEF";
int iPos=0;
for(int i=0; i<numBytes; i++){
//assume buffer contains some binary data at this point
const char cHex=buffer[i];
outbuffer[iPos++]=pHexTable[(cHex>>4)&0x0f];
outbuffer[iPos++]=pHexTable[cHex&0x0f];
}
outbuffer[iPos]='[=10=]';
C++ 中有 stringstream class,在这种情况下可能有用。使用 C 时,三个字节将被打印到具有一个 sprintf-statement sprintf(buffer, "%02x%02x%02x", bytes[0], bytes[1], bytes[2])
(最好是 snprintf
)的缓冲区。
#include <sstream>
#include <iostream>
#include <iomanip>
int main(void)
{
std::stringstream ss;
unsigned char bytes[] = {0xff, 0x00, 0xcc};
ss << std::hex;
// This did not work, 00 was printed as 0
// ss << std::setfill('0') << std::setw(2)
// ...
// ss << (unsigned int)bytes[i]
for (int i=0; i<3; i++) {
unsigned int tmp = bytes[i];
ss << (tmp >> 4) << (tmp & 0xf);
}
std::cout << ss.str();
return 0;
}
据了解,numBytes
可以大于 3 或 4(否则为什么缓冲区大小为 100?)
此外,我更喜欢在使用 string
时使用 C++ classes(你需要 string
,而不是 char[]
?)。
考虑以下带有 stringstream
class 的示例(仅包括 sstream
和 iomanip
标准 headers):
string myString;
stringstream myStringStream;
myStringStream << setbase(16);
myStringStream << uppercase;
for (int i = 0; i < numBytes; i++)
{
myStringStream << (0xFF & (unsigned int) buffer[i]);
}
myString = myStringStream.str();
我无法将我的示例的速度与其他答案进行比较,但此解决方案确实是适用于任何大小 buffer
的 C++ 方法。
我在 Arduino 上使用 C++。
假设我有一个二进制数据流;
二进制数据:0xFF, 0x00, 0x01, 0xCC
我想将其转换为等效的 ASCII 并将其存储在 String 对象类型中。
转换后的字符串应如下所示 "FF0001CC"。
这是一些代码草稿。
char buffer[100];
String myString;
for (int i=0; i < numBytes; i++)
{
//assume buffer contains some binary data at this point
myString += String(buffer[i], HEX);
}
此代码的问题是 myString
包含 FF01CC
,而不是 FF0001CC
。
我的猜测是每次附加文本时字符串 class 都会调整大小,这可以改进。 假设您知道输入大小并且它是常数,您可以试试这个:
char outbuffer[numBytes*2+1];
const char* pHexTable="0123456789ABCDEF";
int iPos=0;
for(int i=0; i<numBytes; i++){
//assume buffer contains some binary data at this point
const char cHex=buffer[i];
outbuffer[iPos++]=pHexTable[(cHex>>4)&0x0f];
outbuffer[iPos++]=pHexTable[cHex&0x0f];
}
outbuffer[iPos]='[=10=]';
C++ 中有 stringstream class,在这种情况下可能有用。使用 C 时,三个字节将被打印到具有一个 sprintf-statement sprintf(buffer, "%02x%02x%02x", bytes[0], bytes[1], bytes[2])
(最好是 snprintf
)的缓冲区。
#include <sstream>
#include <iostream>
#include <iomanip>
int main(void)
{
std::stringstream ss;
unsigned char bytes[] = {0xff, 0x00, 0xcc};
ss << std::hex;
// This did not work, 00 was printed as 0
// ss << std::setfill('0') << std::setw(2)
// ...
// ss << (unsigned int)bytes[i]
for (int i=0; i<3; i++) {
unsigned int tmp = bytes[i];
ss << (tmp >> 4) << (tmp & 0xf);
}
std::cout << ss.str();
return 0;
}
据了解,numBytes
可以大于 3 或 4(否则为什么缓冲区大小为 100?)
此外,我更喜欢在使用 string
时使用 C++ classes(你需要 string
,而不是 char[]
?)。
考虑以下带有 stringstream
class 的示例(仅包括 sstream
和 iomanip
标准 headers):
string myString;
stringstream myStringStream;
myStringStream << setbase(16);
myStringStream << uppercase;
for (int i = 0; i < numBytes; i++)
{
myStringStream << (0xFF & (unsigned int) buffer[i]);
}
myString = myStringStream.str();
我无法将我的示例的速度与其他答案进行比较,但此解决方案确实是适用于任何大小 buffer
的 C++ 方法。