我正在写一个 C++ 实验室。本质是编写一个程序,接收两个文件作为输入,一个带有文本文件,另一个是空文件,在第二个空文件中,单词应该显示在一列中,旁边的数字显示这些单词的数量与文本会面(所有使用超过 1 次的单词都应显示)。本质很简单,原则上,一切都为我解决了,但由于某种原因,在一个地方,当从向量中删除元素时,程序以错误结束。(在另一个地方,我删除了相同的元素仅来自另一个向量的方式,并且没有错误):
for (int j = 0; j < wordsCount; j++) {
if (WordNumber[j] == 1) {
WordNumber.erase(WordNumber.begin()+j);
}
}
这是代码:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <vector>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QString firstFileName = ui->lineEdit->text();
QString secondFileName = ui->lineEdit2->text();
qDebug()<<firstFileName;
qDebug()<<secondFileName;
string thePath = "C:/Users/leoni/Desktop/Science/c++/Qtprojects/Qt projects/build-calcFrequency_lab-Desktop_Qt_6_2_0_MinGW_64_bit-Debug/debug/" + firstFileName.toStdString();
string thePath2 = "C:/Users/leoni/Desktop/Science/c++/Qtprojects/Qt projects/build-calcFrequency_lab-Desktop_Qt_6_2_0_MinGW_64_bit-Debug/debug/" + secondFileName.toStdString();
ifstream fin(thePath);
ofstream fout(thePath2, ios_base::trunc);
string g,t;
int wordsCount = 0;
while (fin>>t) {
wordsCount++;
}
//string words[wordsCount];
vector <string> words(wordsCount);
fin.close();
for (int i = 0; i < wordsCount; i++) {
words[i] = "";
}
fin.open(thePath);
int cnt = -1;
while (fin>>g) {
cnt++;
words[cnt] = g;
}
qDebug()<<wordsCount;
fin.close();
fout.close();
for (int i = 0; i < wordsCount; i++) {
if (words[i] == "," || words[i] == "." || words[i]==":"){
words.erase(words.begin()+i);
}
}
for (int i = 0; i < wordsCount; i++) {
for (int j = 0; j < words[i].length(); j++) {
if (words[i][j] == ','||words[i][j] == '.'||words[i][j] == ':'||words[i][j] == ':'||words[i][j] == '!'||words[i][j] == '?') {
words[i].erase(words[i].begin()+j);
}
}
}
//counting part:
vector <int> WordNumber (wordsCount);
for(int i = 0; i <wordsCount; i++) {
WordNumber[i] = 0;
}
for (int i = 0; i < wordsCount; i++) {
string theWord = "";
for (int j = i; j < wordsCount; j++) {
theWord = words[i];
if (theWord == words[j]) {
WordNumber[i]++;
}
}
}
for (int j = 0; j < wordsCount; j++) {//Вот место ошибки
if (WordNumber[j] == 1) {
WordNumber.erase(WordNumber.begin()+j);
}
}
fout.open(thePath2,ios_base::app);
for (int i = 0; i < cnt+1; i++) {
fout <<words[i]<<" - "<<WordNumber[i]<<endl;
}
fout.close();
}
当我删除这个地方时,一切正常,它只是将所有曾经使用过的单词以及主题输出到文件中。请解释错误是什么,因为在此之前我以相同的方式从向量中删除了元素并且一切正常。请帮帮我。
当你删除元素时,向量的长度会发生什么变化?她在减少。结果,
wordsCount它不再对应于向量的长度,并且您超出了范围...顺便说一句,假设您删除了第二个元素。在
j==2。现在第三个取代了第二个......但您不再检查它 - 移动到一个新值j==3并检查第四个,删除后成为第三个。第三个不见了。在附近的回答中,哈利解释了问题所在。这是解决方案:
此条目适用于任何容器,而不仅仅是那些运行
[...]. 例如在std::list.另一种选择,所谓的。擦除删除成语:
还有
std::remove_if, 它不是一个特定的值,而是一个检查是否应该删除元素的函数。C++20 的另一个选项:
还有一个
std::erase_if,它需要一个函数。