QByteArray 可以用来存储原始字节(包含'\0')和传统8位'\0'结尾字符串(也就是const char *); 使用 QByteArray 比 const char *有更多的便利之处; (1) 它总是能确保数据以'\0'结尾; (2) 使用隐式共享(写时复制)同减少内存使用个避免不必要的数据复制;
除了QByteArray, Qt还提供了QString类来存储字符串数据。 在大多数情况下,QString是您想要使用的类。它存储16位Unicode字符,使得在应用程序中存储非ascii /非latin -1字符变得容易。 此外,QString在Qt API中一直被使用。QByteArray最适合的两种情况是: (a)当你需要存储原始二进制数据时; (b)当节省内存非常重要时(例如,嵌入式Linux下的Qt)。
//初始化QByteArray的一个方法就是将const char*传递给它的构造函数
QByteArray ba("hello");//size()等于5,末尾包含了'\0'
QByteArray对const char *数据进行深度拷贝,因此您可以在以后修改它,而不会遇到副作用。(如果出于性能原因,你不想获取字符数据的深层拷贝,使用QByteArray::fromRawData()代替。)
另一种方法是使用resize()设置数组的大小,并按字节初始化数据。QByteArray使用就像c++数组一样。 要访问位于特定索引位置的字节,可以使用operator[]()。
QByteArray ba;
ba.resize(5);
ba[0] = 'h';
ba[1] = 'e';
ba[2] = 'l';
ba[3] = 'l';
ba[4] = 'o';
qDebug() << ba.data() << endl;//hello
对于只读访问,可以使用at();at比operator[]()更快,它不会深度拷贝;
for(int i = 0; i < ba.size(); i++){
qDebug() << ba.at(i);
}
QByteArray ret = ba.left(2);
qDebug() << ret << endl;//"he"
ret = ba.right(2);
qDebug() << ret << endl;//"lo"
ret = ba.mid(1,3);
qDebug() << ret << endl;//"ell"
ret = ba.mid(1);
qDebug() << ret << endl;//"ello"
QByteArray可以嵌入'\0'字节。size()函数总是返回整个数组的大小,包括嵌入的'\0'字节,但不包括QByteArray添加的终止的'\0'。
不同版本打印constData可能不一样!
QByteArray ba1("ca\0r\0t");
qDebug() << ba1.size() << endl; //2
qDebug() << ba1.constData() << endl;//"ca"
QByteArray ba2("ca\0r\0t",3);
qDebug() << ba2.size() << endl; //3
qDebug() << ba2.constData() << endl;//"ca"
QByteArray ba3("ca\0r\0t",4);
qDebug() << ba3.size() << endl; //4
qDebug() << ba3.constData() << endl;//"ca"
const char cart[] = {'c', 'a', '\0', 'r', '\0', 't'};
QByteArray ba4(QByteArray::fromRawData(cart, 6));
qDebug() << ba4.size() << endl;//6
qDebug() << ba4.constData() << endl;//"ca"
调用resize()后,新分配的字节有未定义的值。要设置所有字节为一个特定的值,调用fill()。
QByteArray ba;
ba.resize(10);//分配10字节,值是未知的;
for(int i = 0; i < 10; i++){
ba.fill(0);//清空
}
qDebug() << QString(ba) << endl;//""
要获得一个指向实际字符数据的指针,可以调用data()或constData()。这些函数返回一个指向数据开头的指针。在QByteArray中调用非const函数之前,该指针保证保持有效。它还保证数据以'\0'字节结束,除非QByteArray是从原始数据创建的。这个'\0'字节由QByteArray自动提供,不计入size()。
QByteArray 还提供了一些基本的函数去改变数据; 其中replace()和remove()函数的前两个参数的第一个为被擦除的起始位置, 第二个参数是擦除的长度; 当你append()一个非空数据时;这个数组将会从新分配然后将新数据分配给它;你可以调用reserve()去 避免这种行为,它会预分配一定数据的内存;可以用capacity()获取实际分配了多少内存;
QByteArray x(" and ");
qDebug() << x.data() ; // and
x.prepend("rock");
qDebug() << x.data(); //rock and
x.append("roll");
qDebug() << x.data(); //rock and roll
x.replace(5,3, "&");
qDebug() << x.data() ; //rock & roll
如果你想找到QByteArray中特定字符或子字符串的所有出现,使用indexOf()或lastIndexOf()。前者从给定的索引位置开始向前搜索,后者向后搜索。如果找到,两者都返回字符或子字符串的索引位置;否则,它们返回-1
QByteArray ba("We must be bold, very bold");
int j = 0;
while ((j = ba.indexOf("", j)) != -1) {
qDebug() << "Found tag at index position " << j << endl;
++j;
}
Found tag at index position 11
Found tag at index position 29
若想去简单检查是否包含字符字串,可以使用contains()
QByteArray ba("We must be bold, very bold");
if(ba.contains("")){
//find
}
如果您想知道某个特定字符或子字符串在字节数组中出现的次数,请使用count() ;
QByteArray ba("We must be bold, very bold");
qDebug() << ba.count("");//2
一个null字节数组总是empty的,但是一个empty字节数组不一定时null
qDebug() << QByteArray().isNull(); // returns true
qDebug() << QByteArray().isEmpty(); // returns true
qDebug() << QByteArray("").isNull(); // returns false
qDebug() << QByteArray("").isEmpty(); // returns true
qDebug() << QByteArray("abc").isNull(); // returns false
qDebug() << QByteArray("abc").isEmpty(); // returns false
其他函数
从字符数组的末尾移除n个字节;
void chop(int n);
示例:
QByteArray ba("STARTTLS\r\n");
ba.chop(2); // ba == "STARTTLS"
清除字节数组的内容并使其为空。
void clear();
QByteArray ba("STARTTLS\r\n");
ba.clear(); // ""
比较函数
int QByteArray::compare(const char *c, Qt::CaseSensitivity cs) const;
QByteArray ba("STARTTLS\r\n");
qDebug() << ba.compare("STARTTLS"); // 1
qDebug() << ba.compare("STARTTLS\r\n"); // 0
qDebug() << ba.compare("STARTTLS\r\nSF"); //-1
qDebug() << ba.compare("staRTTLS\r\n",Qt::CaseInsensitive); //不关心大小写 0
qDebug() << ba.compare("staRTTLS\r\n",Qt::CaseSensitive); //关心大小写 -32
判断是否是以参数中内容为结尾;
bool endsWith(const QByteArray &a) const;
bool endsWith(char c) const;
bool endsWith(const char *c) const;
示例:
QByteArray ba("STARTTLS\r\n");
qDebug() << ba.endsWith("\r\n");//true
如果该字节数组只包含大写字母,则返回true,否则返回false。
(a) bool isUpper() const;
如果该字节数组只包含小写字母,则返回true,否则返回false。
(b) bool isLower() const;
示例:
QByteArray ba("STARTTLS");
qDebug() << ba.isLower();//false
qDebug() << ba.isUpper();//true
(c)
QByteArray toLower() const;
QByteArray toUpper() const;
示例:
QByteArray x("Qt by THE QT COMPANY");
QByteArray y = x.toLower();
// y == "qt by the qt company"
在出现sep的地方将字节数组拆分为子数组,并返回这些数组的列表。如果sep在字节数组中任何地方都不匹配,split()将返回包含该字节数组的单元素列表。
QList split(char sep) const;
示例:
QByteArray ba("STARTTLS");
QList list = ba.split('R');
qDebug() << list.at(0);//STA
qDebug() << list.at(1);//TTLS
base取值为0~36;或者0;
(a)
short toShort(bool *ok = nullptr, int base = 10) const;
ushort toUShort(bool *ok = nullptr, int base = 10) const;
base取值为0~36;或者0;
(b)
int toInt(bool *ok = nullptr, int base = 10) const;
uint toUInt(bool *ok = nullptr, int base = 10) const;
示例:
QByteArray str("FF");
bool ok;
int hex = str.toInt(&ok, 16); // hex == 255, ok == true
int dec = str.toInt(&ok, 10); // dec == 0, ok == false
(c)
long toLong(bool *ok = nullptr, int base = 10) const;
ulong toULong(bool *ok = nullptr, int base = 10) const;
qlonglong toLongLong(bool *ok = nullptr, int base = 10) const;
qulonglong toULongLong(bool *ok = nullptr, int base = 10) const;
示例:
QByteArray str("FF");
bool ok;
long hex = str.toLong(&ok, 16); // hex == 255, ok == true
long dec = str.toLong(&ok, 10); // dec == 0, ok == false
(d)
float toFloat(bool *ok = nullptr) const;
示例:
QByteArray string("1234.56");
bool ok;
float a = string.toFloat(&ok); // a == 1234.56, ok == true
string = "1234.56 Volt";
a = str.toFloat(&ok); // a == 0, ok == false
(e)
double toDouble(bool *ok = nullptr) const;
示例:
QByteArray string("1234.56");
bool ok;
double a = string.toDouble(&ok); // a == 1234.56, ok == true
string = "1234.56 Volt";
a = str.toDouble(&ok); // a == 0, ok == false
(f)
QByteArray toHex() const;
QByteArray toHex(char separator) const; //若separator不是'\0',那么将被插入字符间
示例:
QByteArray macAddress = QByteArray::fromHex("123456abcdef");
macAddress.toHex(':'); // returns "12:34:56:ab:cd:ef"
macAddress.toHex(0); // returns "123456abcdef"
转成标准字符串,内容不变;
std::string QByteArray::toStdString() const
QByteArray ba(" lots\t of\nwhitespace\r\n ");
ba = ba.trimmed(); //返回一个字节数组,该数组从开始和结束处移除空白。
qDebug() << ba << endl; //"lots\t of\nwhitespace"
在索引位置pos处截断字节数组。
QByteArray ba("Stockholm");
ba.truncate(5); // ba == "Stock"