2014-01-28 8 views
-2

Я делаю программу для сортировки строки элементов, разделенных пробелами. Когда я использую первый элемент listt (listt [0]), программа работает отлично, однако, когда я пытаюсь сделать что-нибудь другое, то listt [0], как listt [1] или listt [2], я получаю сообщение об ошибке. Любой вход или совет будут очень признательны.QString :: split ("") работает только для первого элемента

//text from text file 
Brandan Janurary 1 2000 Math 7A 4 9 10 9 10 9 0 0 0 0 0 0 
Brandan Janurary 1 2000 Math 7A 4 9 10 7 10 10 0 0 0 0 0 0 
Brandan Janurary 1 2000 Math 7A 4 10 10 10 10 10 0 0 0 0 0 0 
Bob Janurary 1 2000 Math 7A 4 9 8 10 10 10 0 0 0 0 0 0 
Bob Janurary 1 2000 Math 7A 4 9 8 10 10 10 0 0 0 0 0 0 


//relevant part of code using listt[0] (works) 
void MainWindow::on_pushButton_clicked() 
{ 
    QString line, name; 
    int avglist; 
    QString *reallist; 
    reallist =new QString[10000]; 
    QString *listof; 
    QStringList listt; 
    listof =new QString[10000]; 
    int x=0; 

    name=ui->lineEdit->text(); 

    QFile file("C:/Users/brandan/Desktop/GUIPrograms/Kumonreal.txt"); 

    if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { 
     QTextStream stream(&file); 

     do 
     { 
     line = stream.readLine(); 
     listof[x] = line; 
     qDebug() << line; 
     x++; 
     } while(!line.isNull()); 
    } 

    for (int q=x; q>=0; q--) 
    { 
     QString Parsing; 
     Parsing = listof[q]; 

     listt = Parsing.split(" "); 

     qDebug() << listt[0]; //"name" in string 
     reallist[q] = listt[0]; 


    } 

    int Counter = sort(reallist,x,name); 
    qDebug() << Counter; 

} 
+1

"ошибка" - какая ошибка? Какая линия? Ошибка времени компиляции? Ошибка времени выполнения? Можете ли вы, я не знаю, поделиться этой ошибкой с нами? – Yakk

+0

Ошибка выполнения, когда я нажимаю кнопку. – user3183586

+0

Пожалуйста, будьте более конкретным. Что происходит в какой строке? –

ответ

1

Ваш код не работает из-за двух конкретных ошибок. Сначала я перечислю их. Другие ошибки не приводят к немедленному сбою, но все же ошибки.

  1. Вы читаете пустые строки и результат split() то есть один элемент. Вы пытаетесь получить доступ к несуществующим элементам, и он терпит неудачу.

  2. Ваш второй цикл начинается с недопустимого индекса в listof, так как вы увеличили x слишком далеко. Таким образом, вы пытаетесь получить доступ к пустой строке, построенной по умолчанию, потому что ваш x является слишком большим. Если вам удастся прочитать 10 000 строк, ваш x будет указывать на конец массива: индекс 10 000 недействителен, последний - 9999!

  3. Вы не освобождаете память, выделенную для элементов списков. Используйте интеллектуальные указатели, чтобы помочь вам в этом. Вы должны использовать QScopedArrayPointer для массивов, выделенных new Type[]. Это ошибка (даже если она не сбой!) Использовать QScopedPointer на таких массивах.

  4. Любые дополнительные пробелы в конце строки или внутри линии будут преобразованы в ложные элементы. Перейдите QString::SkipEmptyParts в качестве второго аргумента в split.

  5. Код не отображается, если представлен пустой файл. Ваша проверка на конец файла неверна, вместо этого вы должны использовать stream.atEnd().

  6. Код также не будет работать, если файл не может быть открыт: вы должны немедленно выйти, когда файл не может быть открыт - тогда нет никакого смысла в остальной части кода, и он сохраняет некоторые отступы и упрощает чтение ,

  7. Код не отображается, если представлен файл из более чем 10 000 элементов. У вас есть фиксированные массивы.

  8. Код не будет работать, если какая-либо строка содержит менее двух элементов.

Исправление всех этих ошибок дает этот ужасный код на 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); 
} 
+0

С этим ответом вопрос кажется более подходящим для http://codereview.stackexchange.com ... –

+0

@ user3183586 Карта существует, потому что вы, похоже, хотите отсортировать свой список по имени. Я просто показываю, как это сделать. Это работает, проверенный код. Кроме того, исправления с фиксированным распределением, которые у вас есть, не касаются эффективности, они касаются безопасной практики кодирования. Вы в основном пишете код, который не имеет шансов когда-либо работать правильно. –

+0

Да, это работает, и я действительно могу это понять, спасибо вам большое. И мой код очень плохой, я должен признать, что я все еще новичок в объектно-ориентированном программировании, и это была моя первая «независимая» программа, которую я пытался. Я собираюсь, однако, попытаться подтолкнуть себя за безопасные методы кодирования, потому что я уверен, что кодирование больших программ без этого будет адским. – user3183586

1

возвращаемый тип QString :: сплит() является QStringList не QString *

поэтому в коде должны нравится:

QStringList listt = Parsing.split(" "); 

и доступ как

listt[0] 
listt[1] 
listt[2]... 
+0

Я все еще получаю сообщение об ошибке, используя это, когда я пытаюсь использовать что-либо другое, кроме списка [1]. – user3183586

+0

Также listt был объявлен в начале программы как QStringList – user3183586

+0

, ваши две петли очень сбивают с толку. последний элемент списка кажется, что он всегда равен нулю. – 0xFFFFFFFF

Смежные вопросы