2

我想逐行读取一个文本文件并将每一行添加到一个数组中,我尝试了类似的方法,但是我的数组有问题,什么?

QFile inputFile("C:\\pepoles.txt");
if (inputFile.open(QIODevice::ReadOnly))
{
    QTextStream in(&inputFile);
    QString pepoles[1000];
    while ( !in.atEnd() )
    {
        QString line = in.readLine();
        pepoles[] = line;
    }
    ui->lineEdit->setText(pepoles[0]);
}
else{
    QMessageBox::critical(this, "Ouups",
                          "Le fichier est introuvable ou vide...");
}

inputFile.close();
}

谢谢 !

4

5 回答 5

3

跟踪您已阅读的行数,并用它来索引人们。此外,请确保您没有超出您的阵列容量。

   int lineNum = 0;
   QFile inputFile("C:\\pepoles.txt");
   if (inputFile.open(QIODevice::ReadOnly))
   {
      QTextStream in(&inputFile);
      QString pepoles[1000];
      while ( !in.atEnd() && lineNum < 1000)
      {
         QString line = in.readLine();
         pepoles[lineNum++] = line;
       }
于 2012-10-25T20:14:42.597 回答
1

您需要指定要在哪个位置复制字符串。例如:

pepoles[0] = line;

将字符串复制到数组的第一个元素。显然,您将需要一个变量来遍历数组,以便在每个循环中将新字符串复制到数组中的下一个位置。

您可能应该使用 aQStringList而不是数组来使事情变得更容易和更安全,这样您就不会意外地写到数组的末尾。例如,您可以定义一个pepoles这样的;

QStringList pepoles;

然后,每次您想在末尾附加一个新字符串时,您都可以:

pepoles << line;

这是QStringList有关如何使用它的文档:http: //doc.qt.digia.com/qt/qstringlist.html#details

您也可以使用 anstd::vector<QString>代替:

std::vector<QString> pepoles;

在这种情况下,您在末尾插入字符串:

pepoles.push_back(line);

std::vector这里阅读:http ://www.cplusplus.com/reference/stl/vector

std::vector不是 Qt 的一部分。它由标准 C++ 库提供。

于 2012-10-25T20:13:45.293 回答
1

您应该使用QStringList而不是QString [1000];.

然后你可以简单地添加线

peoples << line;

现在你的语法不正确。您正在尝试分配line给数组,还是什么?您只能分配line给数组的指定元素,例如

peoples[i] = line;

但你最好使用第一种方法。

于 2012-10-25T20:12:56.227 回答
1

这也将只显示第一行:

ui->lineEdit->setText(pepoles[0]);

你可能想要这样的东西(如果 pepoles 是一个 QStringList)

ui->lineEdit->setText(pepoles.join());

join() 方法将创建一个连接 qstringlist 中所有项目的 QString

编辑:也许使用 LineEdit 以外的其他东西;)

于 2012-10-25T20:17:31.293 回答
0

这个问题真的取决于很多事情。您从文本文件中提取的信息的计划内容。您是否要将其输出到另一个文本文件,将其显示在具有文本对象功能(即 QTextEdit、QLineEdit 等)的小部件中,将其发送到数据库,将其用于某种类型(即删除重复条目或定界/删除行距)?有问题的文本文件是否换行?每行有多少个字符,因此有多少位。

我这么说,有很多原因。众所周知,Qt 通过 Meta-Object-Compiler 和扩展的宏丰富了 C++ 语言。回到 C++ 编程的基础,宏在编译器实际看到之前重新排列程序文本。我发现在 Qt 中,这比使用文本对象和文件 I/O 发送到文本对象更真实。再一次,这取决于您如何设计您的应用程序。最好遵循 Bjarne 的建议和“决定你想要哪些类,为每个类提供全套操作,通过使用继承明确共性。没有这种共性的地方,数据抽象就足够了。”。

既然我已经说明了这一点,您可能会在编译期间或编译后遇到运行时错误或应用程序意外崩溃/完成。这意味着您必须重写程序/应用程序以计算您的数据流。

如果您想要文本文件中的数据,那么您可以像二进制搜索算法一样搜索/排序文本,以便使用这样的数组进行比较是行不通的。如果要显示文本对象中的所有名称并搜索那些名称,最好创建 QScrollArea 和 QTextEdit,然后将 QTextEdit 添加到 QScrollArea,如下所示:

scrollArea = new QScrollArea(this);
textEdit = new QTextEdit("",this);
textEdit -> setGeometry(QRect(QPoint(150, 50), QSize(400,20000)));
scrollArea -> setGeometry(QRect(QPoint(150, 50), QSize(400,300)));
scrollArea -> setWidget(textEdit);

*注意:您可以将 textedits 长度的大小设置为超出窗口大小!12 种字体至少有一千行??是20000,南北4分包含线边距。

如果在父对象类中创建了滚动区域和 textedit,则读取文件,使用 readAll 而不是 readLine,然后将其显示在 textEdit 中。一千行的行编辑是巨大的!您不必迭代,在这种情况下,您使用 QFile::ReadOnly 描述的内容就足够了。如果您执行父对象的类(即主窗口)中描述的操作,其中行编辑会创建一个读取文件的 void 函数,并将其显示如下:

textEdit->setPlainText(line);

然后只需调用 mainWindow 函数底部的函数即可。没有必要创建一个数组来连接所描述的字符串。当您使用我所描述的使用小型三到五行功能时可以更轻松地编辑它们。

如果此应用程序不适合您使用并且您可能希望公开:这可能需要通过函数和数据抽象进行计算,并在数组填充后从/向文本对象输入。在这种情况下,创建容器 QStringList 并在文件关闭后使用如下所示的 qFill 算法。

QList<QString> Lstring(lineNumbers); //line numbers is the size of strings per line

qFill(Lstring, peoples.size());

foreach(QString item, Lstring){
    textObjectOfChoice -> setText();
}

我个人更喜欢使用 QStringList,在 MainWindow 的类中创建一个布尔函数,设置为 false(关闭),并在 int main{} 中,一旦应用程序开始执行,当然 MainWindow 或 dialoge 对象已经created 在该对象上调用一个点分隔符,并通过参数传递一个 true 来打开文件加载一次。然后在调用 w.show(); 之后 在递归返回 app.exec() 之前,调用相同的点分隔符函数,然后将值传递给 false。注意:启动画面对此有所帮助。我个人只使用了 50 万字 250 万字符而没有启动画面,它可能会更长,具体取决于您个人在应用程序中编写了多少类。下面是一个将被调用的函数的示例:

void WordGame::fileStart(bool load){

    start = load;

    if (start){
        QFile myfile(":/WordGame/WordGame/TheHundredGrand.txt");

        if(myfile.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            QString line;
            QTextStream stream(&myfile);
            int index = 0;
            int length = 0;
            do
            {
                line = stream.readLine();
                arryOne[index] = line;
                listOne << arryOne[index];
                index++;
                length++;
            }while(index<109582);

            stream.flush();
            myfile.close();
        }
    }
}

在 main 中,将调用 WordGame 主窗口类,如下所示: bool load = true; 文字游戏 w; w.fileStart(加载);

w.show();

w.fileStart(!load);

return app.exec();

这当然是您在 qrc 源文件中引用的单词列表。如果您不创建算法的文件加载部分以在调用应用程序的第一个实例后退出,则列表将继续扩展重复自身(请记住,所有具有标准输入/输出的 c/c++ 应用程序本身都是递归的,因此返回应用程序.exec)。将数据抽象到第一个列表创建功能之外的另一个列表(意味着将解析原始列表),以便可以将其与原始列表进行比较,例如已经回答、以前回答、以前搜索过等。基于文本对象数量的最智能移动。最好只创建另一个用户输入列表,然后迭代初始列表与用户输入列表。我会使用这样的东西:

QStringList::iterator i3 = qFind(userInputList.begin(), userInputList.end(), word);
QStringList::iterator i2 = qFind(listOne.begin(), listOne.end(), word);

在上述迭代器中,一个查找用户条目是否与初始数据集匹配,另一个则针对用户先前的输入进行搜索。

注意:C++ 或 Java 中的函数和或方法应该是 30 行或更少的数据(非空行)。重复地从具有文本对象功能(即 lineEdit)的小部件中抽象和输入数据,并对它们执行计算,如果您按照所述频繁打开文件,以后可能会出现问题。在对另一个函数的 file.closed() 操作完成后,似乎连接语句应该是有序的。或者使用布尔函数 done = true; 坦率地说,这是在 Qt/Cpp(或任何语言)中开发大型健壮软件的最佳方式是二进制(0 或 1)真或假,功能/方法完成。根据您的使用情况,创建 qrc 文件并将文本文件添加为文件也可能很有趣。创建一次打开和关闭以填充数据容器将是脱离主事件循环的方法。如果您使用 Qstringlist,则该列表可能会不断被填充,直到执行内存转储,然后导致应用程序失败。为了避免这种情况,额外的'list-reset'函数将按顺序进行,例如将“”作为列表的每个索引位置的null进行反向迭代。如果用户点击回车按钮或其他东西,或者您正在开发的任何东西,它会自动调用包含 TextStream 对象的函数吗?就像列表的每个索引位置的“”为空的反向迭代一样。如果用户点击回车按钮或其他东西,或者您正在开发的任何东西,它会自动调用包含 TextStream 对象的函数吗?就像列表的每个索引位置的“”为空的反向迭代一样。如果用户点击回车按钮或其他东西,或者您正在开发的任何东西,它会自动调用包含 TextStream 对象的函数吗?

PS如果你真的想对它说实话,你可以像8位风格那样做它真的很老派,*如果你永远知道你的文本文件会是什么,并且是不可变的;并创建(它是什么???)int array[97],它是所有的字母数字加上大写字母加上特殊字符/标点符号等于数组的一个索引位置。例如一个整数等于一个字符,例如[0]=a,[1]=b,[26]=A,并创建一个字母出现程序来计算/绘制每行每个字符的位置,然后一次你有那个特定的word文件或文本文件的统​​计数据,

于 2014-05-08T10:25:17.617 回答