简体   繁体   English

十六进制到字符串转换C ++ / C / Qt?

[英]Hex to String Conversion C++/C/Qt?

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 CR LF是回车换行
  • hh->checksum HH->校验
  • %abcdefg -> header %abcdefg - >标题

Each character in above packet is sent as a hex representation (the xx,yy,abcd etc are replaced with actual numbers). 上面数据包中的每个字符都以十六进制表示形式发送(xx,yy,abcd等被实际数字替换)。 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. 问题出在我的最后,我把它存储在一个const char *中,在隐式转换期间,校验和说0x05转换为\\ 0x05。 Here \\0 being null character terminates my string. 这里\\ 0为空字符终止我的字符串。 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. 这就是程序员的意图。

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. 另外在cutecom(在LINUX RHEL 4上)我检查了串口上的数据,我们也注意到\\0x05而不是5用于校验和。 Note that for storing incoming data I am using 请注意,用于存储我正在使用的传入数据

//store data from serial here
unsigned char Buffer[SIZE];  

//convert to a QString, here is where problem arises 
QString str((const char*)Buffer); of \0

QString is "string" clone of Qt. QString是Qt的“字符串”克隆。 Library is not an issue here I could use STL also, but C++ string library is also doing the same thing. 库不是问题,我也可以使用STL,但C ++字符串库也在做同样的事情。 Has somebody tried this type of experiment before? 以前有人尝试过这种类型的实验吗? Do share your views. 分享您的观点。

EDIT 编辑

This is the sample code you can check for yourself also: 这是您可以自己检查的示例代码:

#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 \0x05";
    cout << "\nHello I am " << "0x05";
    return app.exec();
}
QByteArray text = QByteArray::fromHex("517420697320677265617421");
text.data();            // returns "Qt is great!" 

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. 如果您的0x05转换为char '\\x05' ,那么您没有十六进制值(只有在数字作为字符串时才有意义),但是二进制值。 In C and C++, a char is basically just another integer type with very little added magic. 在C和C ++中, char基本上只是另一种整数类型,几乎没有添加魔法。 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. 因此,如果您有一个5并将其分配给char ,那么您获得的是系统编码定义为第五个字符的任何字符。 (In ASCII , that would be the ENQ char, whatever that means nowadays.) (在ASCII中 ,那将是ENQ char,无论现在意味着什么。)

If what you want instead is the char '5' , then you need to convert the binary value into its string representation. 如果你想要的是char'5 '5' ,那么你需要将二进制值转换为它的字符串表示。 In C++, this is usually done using streams: 在C ++中,这通常使用流完成:

const char ch = 5; // '\0x5'
std::ostringstream oss;
oss << static_cast<int>(ch);
const std::string& str = oss.str(); // str now contains "5"

Of course, the C std library also provides functions for this conversion. 当然,C std库也提供了这种转换的功能。 If streaming is too slow for you, you might try those. 如果流媒体对你来说太慢了,你可以尝试一下。

I think c++ string classes are usually designed to handle zero-terminated char sequences. 我认为c ++字符串类通常用于处理零终止的char序列。 If your data is of known length (as it appears to be) then you could use a std::vector. 如果您的数据具有已知长度(看起来如此),那么您可以使用std :: vector。 This will provide some of the functionality of a string class, whilst ignoring nulls within data. 这将提供字符串类的一些功能,同时忽略数据中的空值。

As I see you want to eliminate control ASCII symbols. 我认为你想要消除控制ASCII符号。 You could do it in the following way: 您可以通过以下方式执行此操作:

#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;
}

The code above prints the following in console: 上面的代码在控制台中打印以下内容:

IFPJKQRC,123.4,T,A,+30.00,A,-30.00,A*.

If you have continuous stream of data you'll get something like: 如果您有连续的数据流,您将获得以下内容:

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*.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM