继续 while 循环直到 EOF (Qt)
Continue a while loop until EOF (Qt)
我正在开发一个从大型 QStringList 创建列表的程序。所以基本上在字符串匹配之后,while 循环将开始将下一个字符串添加到列表中。这部分工作正常。我唯一的问题是程序意外退出,因为我不知道应该如何添加EOF机制。
更新更详细的代码
很抱歉没有提供有关我的代码的足够详细信息。这就是我的代码现在的样子。因此,在第一次检测到字符串 "PACKAGE TYPE" 后,我使用函数 storeLines()
将下一个字符串存储到三个依赖列表之一中。这将一直持续到下一个 "PACKAGE TYPE" 匹配或 EOF。现在唯一不能正常工作的是当迭代器位于 QStringList 的最后一个字符串上时。它以某种方式没有检测到下一个是 inputline.end()
void storeLines(QString department, QStringList::iterator current_line, QStringList::iterator endline){
while(QString::compare(*(current_line + 1),"PACKAGE TYPE") && (++current_line != endline)){ //this is not working
if(!QString::compare(department, "MDA")) mda_list.push_back(*current_line);
else if(!QString::compare(department, "SDA")) sda_list.push_back(*current_line);
else mix_list.push_back(*current_line);
}
}
void void MainWindow::on_pushButton_clicked(){
QString input = ui->listinput->toPlainText().toLatin1();
QStringList inputline = input.split("\n", QString::SkipEmptyParts );
for(QStringList::iterator pkg_header(inputline.begin()); pkg_header != inputline.end(); ++pkg_header){
if(!QString::compare(*pkg_header,"PACKAGE TYPE")){
++pkg_header;
if(!QString::compare(*pkg_header,"Department-mda:")) storeLines("MDA", pkg_header, inputline.end());
else if(!QString::compare(*pkg_header,"Department-sda:")) storeLines("SDA", pkg_header, inputline.end());
else storeLines("MIX", pkg_header, inputline.end());
}
}
}
提前致谢!
您的明显意图是在现有列表中找到字符串 "PACKAGE TYPE",然后将列表中的剩余元素复制到新列表中。
如果是这样,那为什么不完全那样做呢?
for(QStringList::iterator current_line(inputline.begin()); current_line != inputline.end(); ++current_line){
if(!QString::compare(*current_line,"PACKAGE TYPE"){
list.insert(list.end(), ++current_line, inputline.end());
break;
}
}
您正在编写一个解析器 - 通常最简单的方法就是像通常那样编写解析器,方法是使状态明确并按顺序迭代输入流的每个元素。这样你就不会产生任何差一迭代器错误。
此代码符合您问题中的意图,并且很明显您错过了一个案例:当您期待一个部门时,您不会对出现的 PACKAGE TYPE
做出反应。您可以发出错误信号,或保持 DEPARTMENT
状态,但我认为您应该处理它而不是忽略它。
QStringList mda_list, sda_list, mix_list;
void parse(const QString & input) {
enum {
TYPE,
DEPARTMENT,
ITEMS
} state = TYPE;
auto list = &mix_list;
auto const kPackageType = QStringLiteral("PACKAGE TYPE");
for (auto const element : input.split("\n", QString::SkipEmptyParts)) {
switch (state) {
case TYPE:
if (element == kPackageType)
state = DEPARTMENT;
break;
case DEPARTMENT:
if (element == QStringLiteral("Department-mda:"))
list = &mda_list;
else if (element == QStringLiteral("Department-sda:"))
list = &sda_list;
state = ITEMS;
break;
case ITEMS:
if (element == kPackageType)
state = DEPARTMENT;
else
*list << element;
break;
}
}
}
QStringLiteral
的使用为您提供了编译时构建的字符串实例以供比较。如果您删除 QStringLiteral(...)
包装器,该代码将同样有效,但由于不可避免的过早悲观而付出代价。
我正在开发一个从大型 QStringList 创建列表的程序。所以基本上在字符串匹配之后,while 循环将开始将下一个字符串添加到列表中。这部分工作正常。我唯一的问题是程序意外退出,因为我不知道应该如何添加EOF机制。
更新更详细的代码
很抱歉没有提供有关我的代码的足够详细信息。这就是我的代码现在的样子。因此,在第一次检测到字符串 "PACKAGE TYPE" 后,我使用函数 storeLines()
将下一个字符串存储到三个依赖列表之一中。这将一直持续到下一个 "PACKAGE TYPE" 匹配或 EOF。现在唯一不能正常工作的是当迭代器位于 QStringList 的最后一个字符串上时。它以某种方式没有检测到下一个是 inputline.end()
void storeLines(QString department, QStringList::iterator current_line, QStringList::iterator endline){
while(QString::compare(*(current_line + 1),"PACKAGE TYPE") && (++current_line != endline)){ //this is not working
if(!QString::compare(department, "MDA")) mda_list.push_back(*current_line);
else if(!QString::compare(department, "SDA")) sda_list.push_back(*current_line);
else mix_list.push_back(*current_line);
}
}
void void MainWindow::on_pushButton_clicked(){
QString input = ui->listinput->toPlainText().toLatin1();
QStringList inputline = input.split("\n", QString::SkipEmptyParts );
for(QStringList::iterator pkg_header(inputline.begin()); pkg_header != inputline.end(); ++pkg_header){
if(!QString::compare(*pkg_header,"PACKAGE TYPE")){
++pkg_header;
if(!QString::compare(*pkg_header,"Department-mda:")) storeLines("MDA", pkg_header, inputline.end());
else if(!QString::compare(*pkg_header,"Department-sda:")) storeLines("SDA", pkg_header, inputline.end());
else storeLines("MIX", pkg_header, inputline.end());
}
}
}
提前致谢!
您的明显意图是在现有列表中找到字符串 "PACKAGE TYPE",然后将列表中的剩余元素复制到新列表中。
如果是这样,那为什么不完全那样做呢?
for(QStringList::iterator current_line(inputline.begin()); current_line != inputline.end(); ++current_line){
if(!QString::compare(*current_line,"PACKAGE TYPE"){
list.insert(list.end(), ++current_line, inputline.end());
break;
}
}
您正在编写一个解析器 - 通常最简单的方法就是像通常那样编写解析器,方法是使状态明确并按顺序迭代输入流的每个元素。这样你就不会产生任何差一迭代器错误。
此代码符合您问题中的意图,并且很明显您错过了一个案例:当您期待一个部门时,您不会对出现的 PACKAGE TYPE
做出反应。您可以发出错误信号,或保持 DEPARTMENT
状态,但我认为您应该处理它而不是忽略它。
QStringList mda_list, sda_list, mix_list;
void parse(const QString & input) {
enum {
TYPE,
DEPARTMENT,
ITEMS
} state = TYPE;
auto list = &mix_list;
auto const kPackageType = QStringLiteral("PACKAGE TYPE");
for (auto const element : input.split("\n", QString::SkipEmptyParts)) {
switch (state) {
case TYPE:
if (element == kPackageType)
state = DEPARTMENT;
break;
case DEPARTMENT:
if (element == QStringLiteral("Department-mda:"))
list = &mda_list;
else if (element == QStringLiteral("Department-sda:"))
list = &sda_list;
state = ITEMS;
break;
case ITEMS:
if (element == kPackageType)
state = DEPARTMENT;
else
*list << element;
break;
}
}
}
QStringLiteral
的使用为您提供了编译时构建的字符串实例以供比较。如果您删除 QStringLiteral(...)
包装器,该代码将同样有效,但由于不可避免的过早悲观而付出代价。