【问题标题】:C++ Qt - Reading specific portion of a text fileC++ Qt - 读取文本文件的特定部分
【发布时间】:2020-06-06 15:09:53
【问题描述】:

我想读取列表小部件中文本文件的特定部分。我尝试了不同的方法并在网上寻找一些解决方案,但我找不到太多。我是使用 Qt 的新手,但在大多数情况下都相处得很好。

QFile YearInfo("C:/Users/Documents/info.txt");
        YearInfo.open(QIODevice::ReadWrite | QIODevice::Text);
        if(YearInfo.isOpen()){
            QTextStream in(&YearInfo);
            bool readEnabled = false;
            QString outputText, startToken = line, endToken = "*"; // line = "2019"
            while(!in.atEnd()){
               QString getLine = in.readLine();
               if(getLine == endToken){
                   readEnabled = false;
               }

               if(readEnabled){
                   outputText.append(getLine + "\n");
               }

               if(getLine == startToken){
                   readEnabled = true;
               }
            }
            ui->listWidget->addItem(outputText);
        }
            YearInfo.flush();
            YearInfo.close();

文本文件包含:

2019 Position Division Title Date (W.M./R.M./J.R) *

2020 职位部门标题日期(P.M./V.R/S.T) *

【问题讨论】:

  • 你的实际问题是什么?
  • 程序不显示文件的部分。事实上,它什么也没显示,我尝试了很多形式,但似乎我做错了什么。所以我的问题是,为什么我的代码没有显示文本文件的部分?
  • 您的代码似乎很好,并且可以按照您的预期进行。尝试发布您正在使用的文本文件的示例。还要仔细检查调试器或使用qWarning() 添加一些调试消息,startToken 的值是您所期望的,并且文件打开确实成功。希望这会有所帮助 =)
  • 谢谢!我会试试。我将添加文本示例@WilliamSpinelli
  • 我不明白你的问题。每一行中最多可以有一个标记,从 startToken 开始,到 endToken 结束。您要检查每个读取的行是否符合模板。我没听错吗?

标签: c++ qt file qlistwidget


【解决方案1】:

只要您尝试提取按以下方式格式化的一段文本,您编写的代码就可以工作

2019
Position Division Title   <~~ this line is extracted
Date (W.M./R.M./J.R)      <~~ this line is extracted
More stuff                <~~ this line is extracted
*

如果你有以下格式的东西

2019 Position Division
Title Date (W.M./R.M./J.R) *
2019 Position Division Title Date (W.M./R.M./J.R) *

不会提取任何内容,因为您在发现一行包含startToken 时开始提取。结束令牌也是如此。

您可以尝试通过以下方式修改代码中的while 循环

while(!in.atEnd()){
    QString getLine = in.readLine().trimmed();

    if(getLine.startsWith(startToken)){
        readEnabled = true;
    }

    if(readEnabled){
        outputText.append(getLine + "\n");
    }

    if(getLine.endsWith(endToken)){
        readEnabled = false;
    }
}

现在您正在检查startsWith 行是否为startToken。在这里,我还添加了一条trimmed 指令来删除每行开头和结尾的空格(以防万一……)。对于endTokenendsWith 也是如此。

另外,最好以只读模式打开设备,因为无论如何您都不会修改它

YearInfo.open(QIODevice::ReadOnly | QIODevice::Text);

最后的flush也是多余的。

希望这会有所帮助 =)

【讨论】:

  • 感谢您的帮助。是的,我有文本文件将两个标记分开放置,行中没有其他内容。除此之外,我会尝试使用您提供的其他选项。
  • 我已经应用了您的帮助,并且在大多数情况下效果很好。由于我正确放置了文件中的文本,因此我不必使用“startsWith”和“endsWith”(了解其他项目真的很有用,所以谢谢)。哦,我看到使代码 100% 工作的另一件事是我使用了“.trimmed()”,就像你说的那样,并且在“startToken”的初始化中。检查文本文件时,startToken 看起来不错,没有空格,除了 startToken 什么都没有。也许它在保存时增加了一些空间或其他东西,但最终完成了。非常感谢!
【解决方案2】:

要查找字符串的条目,我使用 QRegExp。请注意,由于您有一个类似于 QRegExp 的特殊符号的 stopToken,它可能会更改为 "\*:

#include <QRegExp>
#include <QDebug>

QStringList tokenize(QString line, QString start, QString end)
{
    QRegExp rx(start+".*"+end);
    rx.indexIn(line);
    return rx.capturedTexts();
}

void test()
{
    qDebug()<<tokenize("2019 Position Division Title Date (W.M./R.M./J.R) *", "2019", "\\*");
    // returned ("2019 Position Division Title Date (W.M./R.M./J.R) *")
    qDebug()<<tokenize("2020 Position Division Title Date (P.M./V.R/S.T) *", "2019", "\\*");
    // returned ("")
}

您的函数必须如下所示:

...
while(!in.atEnd()){
    QString getLine = in.readLine();
    QStringList strL = tokenize(getLine, startToken, stopToken);
    if (strL.size())
       ui->listWidget->addItem(strL[0]);
}

【讨论】:

    【解决方案3】:
            QFile YearInfo("C:/Users/Documents/info.txt");
            YearInfo.open(QIODevice::ReadOnly | QIODevice::Text);
            if(YearInfo.isOpen()){
                QTextStream in(&YearInfo);
                bool readEnabled = false;
                QString outputText = "", startToken = line.trimmed(), endToken = "*";
    
                while(!in.atEnd()){
                    QString getLine = in.readLine().trimmed();
    
                    if(getLine == startToken){
                        readEnabled = true;
                    }
    
                    if(readEnabled){
                        outputText.append(getLine + "\n");
                    }
    
                    if(getLine == endToken){
                        readEnabled = false;
                    }
                }
                ui->listWidget->addItem(outputText);
            }
                YearInfo.close();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-13
      • 2011-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多