Ваш код не работает из-за двух конкретных ошибок. Сначала я перечислю их. Другие ошибки не приводят к немедленному сбою, но все же ошибки.
Вы читаете пустые строки и результат split()
то есть один элемент. Вы пытаетесь получить доступ к несуществующим элементам, и он терпит неудачу.
Ваш второй цикл начинается с недопустимого индекса в listof
, так как вы увеличили x
слишком далеко. Таким образом, вы пытаетесь получить доступ к пустой строке, построенной по умолчанию, потому что ваш x
является слишком большим. Если вам удастся прочитать 10 000 строк, ваш x
будет указывать на конец массива: индекс 10 000 недействителен, последний - 9999!
Вы не освобождаете память, выделенную для элементов списков. Используйте интеллектуальные указатели, чтобы помочь вам в этом. Вы должны использовать QScopedArrayPointer
для массивов, выделенных new Type[]
. Это ошибка (даже если она не сбой!) Использовать QScopedPointer
на таких массивах.
Любые дополнительные пробелы в конце строки или внутри линии будут преобразованы в ложные элементы. Перейдите QString::SkipEmptyParts
в качестве второго аргумента в split
.
Код не отображается, если представлен пустой файл. Ваша проверка на конец файла неверна, вместо этого вы должны использовать stream.atEnd()
.
Код также не будет работать, если файл не может быть открыт: вы должны немедленно выйти, когда файл не может быть открыт - тогда нет никакого смысла в остальной части кода, и он сохраняет некоторые отступы и упрощает чтение ,
Код не отображается, если представлен файл из более чем 10 000 элементов. У вас есть фиксированные массивы.
Код не будет работать, если какая-либо строка содержит менее двух элементов.
Исправление всех этих ошибок дает этот ужасный код на C++.Он не откажет и сгореть, он работает «правильно» для файлов с 10000 записей или меньше, но это все-таки плохой код:
void processDataOrg(QIODevice * dev)
{
if (!dev->open(QIODevice::ReadOnly | QIODevice::Text)) return;
const int N = 10000;
QScopedArrayPointer<QString> listof(new QString[N]);
QTextStream stream(dev);
int x = -1; /* FIX for problem #2 */
while (!stream.atEnd()) {
QString line = stream.readLine();
listof[++x] = line; /* FIX for problem #2 */
if (x == N-1) break;
}
QScopedArrayPointer<QString> reallist(new QString[N]);
for (int q=x; q>=0; q--) {
QString Parsing = listof[q];
QStringList listt = Parsing.split(" ", QString::SkipEmptyParts);
if (listt.size() < 2) continue; /* FIX for problem #1 */
qDebug() << listt[0] << listt[1];
reallist[q] = listt[0];
}
}
Конечно, вы бы не эти проблемы, если вы с помощью как они должны были использоваться! Для добавления в список вам не нужно отслеживать какие-либо индексы. Вам не нужно беспокоиться об индексах при повторении списка. Вы кодируете, как если бы это был C, а не C++. Ваш код может быть упрощен, как показано ниже.
void processDataBetter(QIODevice * dev)
{
if (!dev->open(QIODevice::ReadOnly | QIODevice::Text)) return;
QStringList lines;
QTextStream stream(dev);
while (! stream.atEnd()) {
lines << stream.readLine();
}
QStringList names;
foreach (QString line, lines) {
QStringList elements = line.split(' ', QString::SkipEmptyParts);
if (elements.size() < 2) continue;
qDebug() << elements[0] << elements[1];
names << elements[0];
}
}
Он по-прежнему не имеет никакого смысла держать lines
список, так:
void processDataOK(QIODevice * dev)
{
if (!dev->open(QIODevice::ReadOnly | QIODevice::Text)) return;
QStringList names;
QTextStream stream(dev);
while (! stream.atEnd()) {
QString line = stream.readLine();
QStringList elements = line.split(' ', QString::SkipEmptyParts);
if (elements.size() < 2) continue;
qDebug() << elements[0] << elements[1];
names << elements[0];
}
}
Поскольку вы, кажется, хотите сортировать данные по имени, вы можете использовать QMap
как структура данных что неявно сортирует свои записи по ключу.
Для нашего теста мы можем использовать QBuffer
вместо QFile
, чтобы иметь автономный пример с одним файлом. Вывод сортируются по имени:
"Bob" "Janurary"
"Bob" "Janurary"
"Brandan" "Janurary"
"Brandan" "Janurary"
"Brandan" "Janurary"
Наконец, достаточно правильно, самодостаточный пример:
#include <QBuffer>
#include <QTextStream>
#include <QStringList>
#include <QMultiMap>
#include <QDebug>
QByteArray fileData(
"Brandan Janurary 1 2000 Math 7A 4 9 10 9 10 9 0 0 0 0 0 0\n"
"Brandan Janurary 1 2000 Math 7A 4 9 10 7 10 10 0 0 0 0 0 0\n"
"Brandan Janurary 1 2000 Math 7A 4 10 10 10 10 10 0 0 0 0 0 0\n"
"Bob Janurary 1 2000 Math 7A 4 9 8 10 10 10 0 0 0 0 0 0\n"
"Bob Janurary 1 2000 Math 7A 4 9 8 10 10 10 0 0 0 0 0 0");
void processData(QIODevice * dev)
{
if (! dev->open(QIODevice::ReadOnly | QIODevice::Text)) return;
typedef QMultiMap<QString, QStringList> Map;
Map map;
QTextStream stream(dev);
while(! stream.atEnd()) {
QString line = stream.readLine().trimmed();
QStringList elements = line.split(' ', QString::SkipEmptyParts);
if (elements.count() < 2) continue;
QString name = elements[0];
map.insert(name, elements);
}
for (Map::const_iterator it = map.begin(); it != map.end(); ++it) {
qDebug() << it.key() << it.value()[1];
}
}
int main()
{
QBuffer buf(&fileData);
processData(&buf);
}
"ошибка" - какая ошибка? Какая линия? Ошибка времени компиляции? Ошибка времени выполнения? Можете ли вы, я не знаю, поделиться этой ошибкой с нами? – Yakk
Ошибка выполнения, когда я нажимаю кнопку. – user3183586
Пожалуйста, будьте более конкретным. Что происходит в какой строке? –