我正在制作一个程序,用空格分隔一系列项目。当我使用listt的第一个元素(listt [0])时,程序运行完全正常,但是当我尝试其他任何其他时,listt [0]如listt [1]或listt [2]我得到一个错误。任何意见或建议将不胜感激。
//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;
}
答案 0 :(得分:1)
QString :: split()的返回类型是QStringList而不是QString *
所以你的代码应该是这样的:
QStringList listt = Parsing.split(" ");
和访问类似
listt[0]
listt[1]
listt[2]...
答案 1 :(得分:1)
由于两个特定的错误,您的代码失败了。我先列出它们。其他错误不会立即失败,但仍然是错误。
您正在阅读空行,split()
的结果会有一个元素。您正在尝试访问不存在的元素,但它失败了。
您的第二个循环从listof
的无效索引开始,因为您已将x
增加太多。因此,您尝试访问默认构造的空字符串,因为x
太大了。如果你碰巧读了10,000行,你的x
将指向数组末尾:索引10,000无效,最后一行是9,999!
您不会释放为列表元素分配的内存。使用智能指针来帮助您解决这个问题。对于使用QScopedArrayPointer
分配的数组,您应该使用new Type[]
。在这样的数组上使用QScopedPointer
是一个错误(即使它没有崩溃!)。
该行末尾或行内的任何多余空格将转换为虚假元素。将QString::SkipEmptyParts
作为第二个参数传递给split
。
如果显示空文件,代码将失败。检查文件结尾是错误的,您应该使用stream.atEnd()
代替。
如果无法打开文件,代码也会失败:当文件无法打开时你应该立即退出 - 那时代码的其余部分没有任何意义,它可以节省一些缩进并使其更容易读取。
如果提供的文件超过10,000个元素,代码将失败:您有固定大小的数组。
如果任何行包含少于2个元素,代码将失败。
修复所有这些错误会产生这个可怕的C ++代码。它不会崩溃和刻录,对于包含10,000个条目或更少条目的文件,它“正常”工作,但它仍然是错误代码:
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);
}