十六进制到字符串的转换 C++/C/Qt?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1258718/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hex to String Conversion C++/C/Qt?
提问by rocknroll
I am interfacing with an external device which is sending data in hex format. It is of form
我正在与以十六进制格式发送数据的外部设备连接。它是形式
> %abcdefg,+xxx.x,T,+yy.yy,T,+zz.zz,T,A*hhCRLF
- CR LF is carriage return line feed
- hh->checksum
- %abcdefg -> header
- CR LF 是回车换行
- hh->校验和
- %abcdefg -> 标题
Each character in above packet is sent as a hex representation (the xx,yy,abcd etc are replaced with actual numbers). The problem is at my end I store it in a const char* and during the implicit conversion the checksum say 0x05 is converted to \0x05. Here \0 being null character terminates my string. This is perceived as incorrect frames when it is not. Though I can change the implementation to processing raw bytes (in hex form) but I was just wondering whether there is another way out, because it greatly simplifies processing of bytes. And this is what programmers are meant to do.
上述数据包中的每个字符都以十六进制表示形式发送(xx、yy、abcd 等被实际数字替换)。问题是在我的最后我将它存储在一个 const char* 中,并且在隐式转换期间校验和说 0x05 被转换为 \0x05。这里 \0 是空字符终止我的字符串。当它不是时,这被认为是不正确的帧。虽然我可以将实现更改为处理原始字节(以十六进制形式),但我只是想知道是否还有另一种出路,因为它大大简化了字节的处理。这就是程序员应该做的事情。
Also in cutecom (on LINUX RHEL 4) I checked the data on serial port and there also we noticed \0x05
instead of 5 for checksum.
Note that for storing incoming data I am using
同样在cutecom(在LINUX RHEL 4上)我检查了串行端口上的数据,我们还注意到\0x05
校验和不是5。请注意,为了存储我正在使用的传入数据
//store data from serial here
unsigned char Buffer[SIZE];
//convert to a QString, here is where problem arises
QString str((const char*)Buffer); of #include <iostream>
#include <string>
#include <QString>
#include <QApplication>
#include <QByteArray>
using std::cout;
using std::string;
using std::endl;
int main(int argc,char* argv[])
{
QApplication app(argc,argv);
int x = 0x05;
const char mydata[] = {
0x00, 0x00, 0x03, 0x84, 0x78, 0x9c, 0x3b, 0x76,
0xec, 0x18, 0xc3, 0x31, 0x0a, 0xf1, 0xcc, 0x99};
QByteArray data = QByteArray::fromRawData(mydata, sizeof(mydata));
printf("Hello %s\n",data.data());
string str("Hello ");
unsigned char ch[]={22,5,6,7,4};
QString s((const char*)ch);
qDebug("Hello %s",qPrintable(s));
cout << str << x ;
cout << "\nHello I am QByteArray text = QByteArray::fromHex("517420697320677265617421");
text.data(); // returns "Qt is great!"
x05";
cout << "\nHello I am " << "0x05";
return app.exec();
}
QString is "string" clone of Qt. Library is not an issue here I could use STL also, but C++ string library is also doing the same thing. Has somebody tried this type of experiment before? Do share your views.
QString 是 Qt 的“字符串”克隆。库在这里不是问题,我也可以使用 STL,但 C++ 字符串库也在做同样的事情。以前有人尝试过这种类型的实验吗?请分享您的观点。
EDIT
编辑
This is the sample code you can check for yourself also:
这是您也可以自己检查的示例代码:
const char ch = 5; // '#include <iostream>
#include <string>
#include <QtCore/QString>
#include <QtCore/QByteArray>
using namespace std;
// test data from your comment
char data[] = { 0x49, 0x46, 0x50, 0x4a, 0x4b, 0x51, 0x52, 0x43, 0x2c, 0x31,
0x32, 0x33, 0x2e, 0x34, 0x2c, 0x54, 0x2c, 0x41, 0x2c, 0x2b,
0x33, 0x30, 0x2e, 0x30, 0x30, 0x2c, 0x41, 0x2c, 0x2d, 0x33,
0x30, 0x2e, 0x30, 0x30, 0x2c, 0x41, 0x2a, 0x05, 0x0d, 0x0a };
// functor to remove control characters
struct toAscii
{
// values >127 will be eliminated too
char operator ()( char value ) const { if ( value < 32 && value != 0x0d && value != 0x0a ) return '.'; else return value; }
};
int main(int argc,char* argv[])
{
string s;
transform( &data[0], &data[sizeof(data)], back_inserter(s), toAscii() );
cout << s; // STL string
// convert to QString ( if necessary )
QString str = QString::fromStdString( s );
QByteArray d = str.toAscii();
cout << d.data(); // QString
return 0;
}
x5'
std::ostringstream oss;
oss << static_cast<int>(ch);
const std::string& str = oss.str(); // str now contains "5"
回答by ufukgun
IFPJKQRC,123.4,T,A,+30.00,A,-30.00,A*.
回答by sbi
If your 0x05
is converted to the char
'\x05'
, then you're not having hexadecimal values (that only makes sense if you have numbers as strings anyway), but binary ones. In C and C++, a char
is basically just another integer type with very little added magic. So if you have a 5
and assign this to a char
, what you get is whatever character your system's encoding defines as the fifth character. (In ASCII, that would be the ENQ
char, whatever that means nowadays.)
如果您0x05
转换为char
'\x05'
,那么您没有十六进制值(只有在您将数字作为字符串时才有意义),而是二进制值。在 C 和 C++ 中, achar
基本上只是另一种整数类型,几乎没有添加魔法。因此,如果您有 a5
并将其分配给 a char
,则您得到的是系统编码定义为第五个字符的任何字符。(在ASCII 中,这将是ENQ
字符,无论现在是什么意思。)
If what you want instead is the char '5'
, then you need to convert the binary value into its string representation. In C++, this is usually done using streams:
如果您想要的是 char '5'
,那么您需要将二进制值转换为其字符串表示形式。在 C++ 中,这通常使用流来完成:
IFPJKQRC,123.4,T,A,+30.00,A,-30.00,A*.
IFPJKQRC,123.4,T,A,+30.00,A,-30.00,A*.
IFPJKQRC,123.4,T,A,+30.00,A,-30.00,A*.
IFPJKQRC,123.4,T,A,+30.00,A,-30.00,A*.
IFPJKQRC,123.4,T,A,+30.00,A,-30.00,A*.
Of course, the C std library also provides functions for this conversion. If streaming is too slow for you, you might try those.
当然,C std 库也提供了这种转换的函数。如果流式传输对您来说太慢,您可以尝试这些。
回答by jon-hanson
I think c++ string classes are usually designed to handle zero-terminated char sequences. If your data is of known length (as it appears to be) then you could use a std::vector. This will provide some of the functionality of a string class, whilst ignoring nulls within data.
我认为 c++ 字符串类通常旨在处理以零结尾的字符序列。如果您的数据长度已知(看起来是这样),那么您可以使用 std::vector。这将提供字符串类的一些功能,同时忽略数据中的空值。
回答by Kirill V. Lyadvinsky
As I see you want to eliminate control ASCII symbols. You could do it in the following way:
正如我所看到的,您想消除控制 ASCII 符号。你可以通过以下方式做到这一点:
##代码##The code above prints the following in console:
上面的代码在控制台中打印以下内容:
##代码##If you have continuous stream of data you'll get something like:
如果你有连续的数据流,你会得到类似的东西:
##代码##