简体   繁体   中英

Qt QTextStream to QList item

I would like to fill QList directly using QTextStream. I have this code working right:

QList<int> str;

QFile file_read1("C:/Programs/file.txt");
if(file_read1.open(QFile::ReadOnly))
{
    QTextStream read1(&file_read1);
    read1.seek(0);
    int i=0;
    int aux=0;
    while (!read1.atEnd())
    {
        read1>>aux;
        str.append(aux);
        //read1>>str[i];  //I'd like to use something like this
        //i++;
    }
}

return a.exec();
}

And I wonder why the commented code inside the while loop doesn't work correctly when uncommented (and read1>>aux;str.append(aux); commented). I can use it, but str.count() returns 0 and str.isEmpty is true even if I can read values using str.at(i).

I there another solution like the commented one where I dont need to use the auxiliary variable aux ?

//read1>>str[i];  //I'd like to use something like this

Yes you can, T & QList::operator[](int i) in your case returns an int & , which is exactly what the stream output operator needs. But you need to have enough space in the list, because unlike append() the [] operator will not increase the size to the list, try to access an invalid index and your app crashes. This is why count is 0 and isEmpty is true. Being able to read from it is aa lucky coincidence, and likely undefined behavior.

Unfortunately, QList doesn't come with a resize() method, nor with a constructor which can set the size. You can still reserve() but that will only help you with avoiding reallocations. It will not increase the size of the list, only the capacity, so as far as the list is concerned, even if you reserve and are able to read and write using the [] operator, its size will remain 0. You can simply go for QVector instead. It has both a QVector(int size) constructor, and a void resize(int size) method. And will be more efficient in your case, since QList reserves capacity at both ends. QList was invented as a sort of a "jack of all trades" but in some cases it is useless.

Note that you can still effectively resize the list by using reserve(n) and appending an n count of dummy integer values, if you are really set on using it instead of a vector.

template<class T>
void resizeList(QList<T> & list, int newSize) {
    int diff = newSize - list.size();
    T t;
    if (diff > 0) {
        list.reserve(diff);
        while (diff--) list.append(t);
    } else if (diff < 0) list.erase(list.end() + diff, list.end());
}

You can also read1 >> str[i++]; and save a line of code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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