QT QByteArray类使用

       提供一个字节数组,QByteArray可用于存储原始字节(包括“\ 0” )和传统的8位 “\ 0” 端接字符串 . 使用QByteArray比使用const char *更方便.
       Qt中的QByteArray储存的十六进制数是0xFF,实际是以ASCII码储存的,储存形式为‘\xFF’,所以如果需要比较的话,需要用array.at(0)=='\xff’表示,而不是array.at(0)==0xFF。

构造函数

一种初始化QByteArray方式是给他的构造函数传入一个const char*即可,此时执行了深度拷贝。

如果出于效率问题不想进行深度拷贝,则使用QByteArray::fromRawData(const char* data, int size)。返回的对象直接和数据指针产生关联。注意:通过这种方式创建时,不包含尾随的终止符,QByteArray不会自动添加,除非通过深度拷贝。

访问和赋值

        访问QByteArray主要有4中方式,分别为[]at()data[]constData[]其中[]data[]为可读可写at()constData[]仅为可读如果仅是读,则通过at()constData[]访问速度最快,因可避免复制处理。示例如下:

QByteArray    ba;

ba.resize(6);

ba[0] = 0x3c;

ba[1] = 0xb8;

ba[2] = 0x64;

ba[3] = 0x18;

ba[4] = 0xca;

ba.data()[5] = 0x31;

一次取出多个字符

    QByteArray    QByteArray::left(int len) const:  从最左边开始取出len长度的字符
    QByteArray    QByteArray::right(int len) const:从最右边开始取出len长度的字符
    QByteArray    QByteArray::mid(int pos, int len = -1)  const:从pos开始,返回指定长度的数组,如果len=-1(默认)或者pos+len>size(),则返回从指定pos开始到数组尾的所有字节。

获取数据指针

    char*          QByteArray::data()           
    const char* QByteArray::constData()  const   
    通过data()或者constData()可以获取QByteArray的真实数据指针。

修改字节的方法

     QByteArray提供了很多修改字节的方法:append()、prepend()、insert()、replace()、remove()。

hex转换

把Hex编码转换为char存储到QByteArray:

QByteArray text = QByteArray::fromHex("517420697320677265617421");

text.data();     

// returns "Qt is great!"

QByteArray转为Hex编码:

QByteArray   ba;

ba.resize(3);

ba[0] = 0x30;

ba[1] = 0x31;

ba[2] = 0x32;

qDebug() << ba.toHex(); //return "303132"

数值转换与输出

尽管QByteArray是一个集合,但也可以作为一个特殊形式的数值用,其灵活的转换格式,可大大方便各种格式数据转换与显示的需求。如显示二进制和十六进制、显示科学计数和指定小数位的数值。示例如下:
把单个字符转为2-36进制数据格式:

int n = 63;

qDebug()<<QByteArray::number(n);       

// returns "63"

qDebug()<<QByteArray::number(n, 16);     

// returns "3f"

qDebug()<<QByteArray::number(n, 16).toUpper(); 

// returns "3F"

qDebug()<<QByteArray::number(n, 2);     

// returns "111111"

qDebug()<<QByteArray::number(n, 8);     

// returns "77"

按照指定进制格式直接复制,其中n可以是各类常见数值类型:

QbyteArray    ba;

int                  n = 63;

ba.setNum(n);         // ba == "63"

ba.setNum(n, 16);    // ba == "3f"

把数值按指定格式和小数位转换输出,小数位四舍五入:

QByteArray    ba1 = QByteArray::number(12.3456, 'E', 3);

QByteArray    ba2 = QByteArray::number(12.3456, 'f', 3);

qDebug()<<ba1;                     // returns "1.235E+01"

qDebug()<<ba2;                     // returns "12.346"

字符串数值转换为各类数值

QByteArray若为数值,可通过to**方法转为各种类型数据,示例如下:

QbyteArray    strInt("1234");

bool               ok0;

qDebug() << strInt.toInt();  // return 1234

qDebug() << strInt.toInt(&ok0,16);

 // return 4660, 默认把strInt作为16进制的1234,对应十进制数值为4660 

QByteArray string("1234.56"); bool ok1; qDebug() << string.toInt();  // return 0, 小数均视为0

qDebug() << string.toInt(&ok1,16);  // return 0, 小数均视为0

qDebug() << string.toFloat();  // return 1234.56

qDebug() << string.toDouble();  // return 1234.56 

QByteArray str("FF");

bool     ok2;

qDebug() << str.toInt(&ok2, 16);   // return 255, ok2 == true

qDebug() << str.toInt(&ok2, 10);   // return 0, ok == false, 转为十进制失败

大小写转换

QByteArray若为带大小写的字符串,可通过toUpper()和toLower()方法实现大小写转换,示例如下:

QByteArray    x("Qt by THE QT COMPANY");

QByteArray    y = x.toLower(); // y == "qt by the qt company" 

QbyteArray    z = x.toUpper();  // z == "QT BY THE QT COMPANY"

与字符串互转

QByteArray与QString互转极为简单,二者从本质上类似,都是连续存储,区别是前者可以存无法显示的字符,后者只存可显示的字符。如QByteArray可以存0x00-0x19,而QString则存储如0x30等可显示字符(0x20-0x7E)。可显示字符可参见ASCII表。
字符型
QByteArray转为QString示例:

QByteArray转为QString示例:

QbyteArray  ba("abc123"); QString str = ba;   

//str.prepend(ba); qDebug()<<str ; //输出:"abc123"

QString转为QByteArray示例:

QString str("abc123"); QByteArray ba = str.toLatin1(); qDebug()<<ba;

//输出:"abc123"

数组型

QByteArray数组转为QString字符串,中间加入空格:

log.append(serialPort->recvDataArray->toHex(' '));

qDebug() << log.toUpper();

QString字符串转为QByteArray数组,中间去掉空格:

QString text = tEditSource->toPlainText().remove(QRegExp("\\s"));

QByteArray   array;   ok;

arrasize(text.length() / 2);

for (int 0; i < text.count();)

{     

         ardata() = (uint8_t)text.mid(i, 2).toInt(&ok, 16);     

         i += 2;

}

与自定义结构体之间的转换

结构体转QByteArray

SHT30RecvBufferTypedef      sendBuffer;

sendBuffer.tempH = 0x01;

sendBuffer.tempL = 0x02;

sendBuffer.tempCRC = 0x03;

sendBuffer.humiH = 0x04;

sendBuffer.humiL = 0x05;

sendBuffer.humiCRC = 0x06; 

QByteArray           sendByte;

sendByte.append((char*)&sendBuffer, sizeof(sendBuffer));

QByteArray转结构体

SHT30RecvBufferTypedef* SHT30RecvBuffer = (SHT30RecvBufferTypedef*)buf.data();

拼接2个QByteArray

QByteArray       x("free");

QByteArray       y("dom");

x.append(y);                          // x == "freedom"

截取部分字节组成新的QByteArray

可以调用mid函数,从哪个pos开始截取,截取的长度是多少。

QbyteArray       x("Five pineapples");

QByteArray       y = x.mid(5, 4);

带空格字符串转hex

void   String2Hex(QString   str, QByteArray*  sendData)

{

QString     str1 = str.trimmed();

sendData->resize((str1.length() + 1) / 3);

 int           index = 0;             

        bool        ok;           

        for (int  i = 0; i < str1.length();)          

 {

                sendData->data()[index] = str1.mid(i , 2).toInt(&ok, 16);         

                index++;                             

                i += 3;             

 }

}

初始化QByteArray

方法一:const char *将其传递给其构造函数。例如,以下代码创建一个大小为5的字节数组,

其中包含数据“Hello”

QByteArray      ba("Hello");

虽然size()为5,但是字节数组在最后还会保留一个额外的’\ 0’字符,

以便如果使用一个函数来请求指向底层数据的指针(例如调用data()),那么指出的数据保证被’\ 0’终止。

方法二:使用resize()设置数组的大小,并初始化每个字节的数据字节.

QByteArray使用基于0的索引,就像C ++数组一样。

要访问特定索引位置的字节,可以使用operator[] ()在非 常量字节数组上,operator 返回一个可以在赋值左侧使用的字节的引用。例如:

QByteArray      ba;

 ba.resize(5);

 ba[0] = 0x3c;

 ba[1] = 0xb8;

 ba[2] = 0x64;

 ba[3] = 0x18;

 ba[4] = 0xca;

 //对于只读访问,替代语法是使用at():

 for (int  i = 0; i < ba.size(); ++i)

 {

     if (ba.at(i) >= 'a' && ba.at(i) <= 'f')

     cout << "Found character in range [a-f]" << endl;

 }

at()可以比operator []()更快,因为它不会导致深层拷贝发生。

要一次提取多个字节,请使用 left(),right() 或mid()。

QByteArray可以嵌入“\0” 字节,size()函数总是返回整个数组的大小,包括嵌入的’\ 0’字节,但不包括QByteArray添加的终止’\ 0’.

调用resize()后,新分配的字节具有未定义的值。 要将所有字节设置为特定值,请调用fill()。

要获取指向实际字符数据的指针,请调用data()或constData()。这些函数返回一个指向数据开头的指针。

指针保持有效,直到在QByteArray上调用了非const函数。除了从原始数据创建QByteArray之外,还保证数据以”\ 0”字节结尾。这个’\ 0’字节由QByteArray自动提供,并不会在size()中计算。

QByteArray类提供以下用于修改字节数据的基本功能:append(),prepend() ,insert(),replace()和remove()。

QByteArray      x("and");

x.prepend("rock ");         // x == "rock and"  前置

x.append(" roll");          // x == "rock and roll" 附加

x.replace(5, 3, "&");       // x == "rock & roll" 替代

这个 replace() 和remove()函数,前两个参数是从其开始擦除的位置和应该被擦除的字节数。

一个常见的要求是从字节数组(’\ n’,’\ t’,’等)中删除空白字符,如果要从QByteArray两端删除空格,请使用trimmed()。

如果要从两端移除空格并用字符数组中的单个空格替换多个连续的空格,请使用simplified()。

如果要查找QByteArray中特定字符或子字符串的所有出现,请使用indexOf()或lastIndexOf()。

indexOf()从给定的索引位置开始搜索,lastIndexOf()向后搜索。两者返回字符或子字符串的索引位置,

如果它们找到它; 否则返回-1 。例如,这是一个典型的循环,它查找特定子字符串的所有出现:

QByteArray ba("We must be <b>bold</b>, very <b>bold</b>");

int     j = 0;

while ((j = ba.indexOf("<b>", j)) != -1)

{

        cout << "Found <b> tag at index position " << j << endl;

        ++j;

}

如果您只想检查QByteArray是否包含特定字符或子字符串,请使用contains()。

如果要查找字节数组中特定字符或子字符串的次数,请使用count()。

如果要将特定值的所有出现替换为另一个,请使用两个参数replace()重载之一。

可以使用运算符<(),运算符<=(),运算符==(),运算符>=()等重载运算符来比较QByteArray。比较完全基于字符的数值,非常快,但不是我们期望的。QString :: localeAwareCompare()是排序用户界面字符串的更好选择。

由于历史原因,QByteArray区分了一个Null byte 和 empty byte. 我们建议您始终使用isEmpty().

二、成员函数

函数一: char  *QByteArray::data()

返回指向字节数组中存储的数据的指针。该指针可用于访问和修改组成数组的字节。具体访问字节数组中的某一个,采用ba.data()[0]–>访问第0个

QByteArray     ba("Hello world");

char   *data = ba.data(); //返回一个指向字节数组ba的数据指针,指向第一个字符

qDebug() << ba.data();  //打印整个字符

while (*data)

{

    cout << "[" << *data << "]" << endl;

    ++data;

}

得到结果 [ H ] ,[ e ] ,[ l ] ,[ l ] ,[ o ], [ ], [ w ] ,[ r ] ,[ l ] ,[ d ].

函数二:QByteArray &QByteArray::fill(char ch, int size = -1)

将字节数组中的每个字节设置为字符ch。如果size与-1(默认值)不同,则字节数组将预先调整为大小。

QByteArray     ba("Istambul");

ba.fill('o');

// ba == "oooooooo"

ba.fill('X', 2);

// ba == "XX"

函数三:int QByteArray::indexOf(const QByteArray &ba, int from = 0) const
返回该字节数组中第一次出现字节数组ba的索引位置,从索引位置向前搜索。如果找不到ba,则返回-1

eg:

QByteArray              x("sticky question");

QByteArray              y("sti");

x.indexOf(y);               // returns 0

x.indexOf(y, 1);            // returns 10

x.indexOf(y, 10);           // returns 10

x.indexOf(y, 11);           // returns -1

函数四:bool QByteArray::isEmpty() const

如果字节数组的大小为0,返回true; 否则返回false。

函数五:QByteArray QByteArray::left(int len) const

返回一个包含该字节数组最左侧len个字节的字节数组,如果len大于size(),则返回整个字节数组.

eg:

QByteArray      x("Pineapple");

QByteArray      y = x.left(4);                  // y == "Pine"

函数六:QByteArray QByteArray::number(int n, int base = 10)
返回一个字节数组,其中包含等价于数字n到基数的字符串(默认为10)。基数可以是236之间的任何值。

eg

int             n = 63;

QByteArray::number(n);                                  // returns "63"

QByteArray::number(n, 16);                             // returns "3f"

QByteArray::number(n, 16).toUpper();             // returns "3F"

可以理解为 int 类型到QByteArray类型的转化。

函数七:QByteArray &QByteArray::setNum(int n, int base = 10)

将字节数组设置为基数为n的打印值(默认为10)并返回对字节数组的引用。基数可以是介于2和36之间的任何值。对于非10以外的其他值,n被视为无符号整数。

eg:

QByteArray            ba;

int n = 63;

ba.setNum(n);            // ba == "63"

ba.setNum(n, 16);       // ba == "3f"

函数八:int QByteArray::size() const

返回此字节数组中的字节数。 

eg:

QByteArray      ba("Hello");

int        n = ba.size();          // n == 5

ba.data()[0];               // returns 'H'  操作某一位的方法

ba.data()[4];               // returns 'o'

ba.data()[5];               // returns '\0'

函数九:

double   QByteArray::toDouble(bool *ok = Q_NULLPTR) const

float      QByteArray::toFloat(bool *ok = Q_NULLPTR) const

int         QByteArray::toInt(bool *ok = Q_NULLPTR, int base = 10) const

返回转换为double值的字节数组。

eg:

QByteArray         string("1234.56");

double                a = string.toDouble();               // a == 1234.56

函数十:QByteArray QByteArray::toHex()    const

返回字节数组的十六进制编码副本。十六进制编码使用数字 0 - 9 和字母 a - f。

See also fromHex().

函数十一:std::string QByteArray::toStdString()    const

返回std :: string对象,带有QByteArray中包含的数据的.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值