我正在主函数中打开一个文件。我想将此文件传递给几个函数,但看起来第一个调用的函数正在清除此文件。 这是一个文件:
1 5 6 8
6 5
1
2 6 8
6 7 5 1 2 4
第一个函数对文件中的行进行计数。第二个函数计算单个数字的数量。
int countTransactions(ifstream &dataBaseFile) {
int numOfTransactions = 0;
string line;
while(getline(dataBaseFile, line))
numOfTransactions++;
cout << "countTransaction" << endl;
cout << numOfTransactions << endl;
return numOfTransactions;
}
void countItems(ifstream &dataBaseFile) {
map<int, int> items;
map<int, int>::iterator it;
int item;
while(!dataBaseFile.eof()) {
dataBaseFile >> item;
it = items.find(item);
if(it != items.end()) {
it->second++;
continue;
} else items.insert(make_pair(item, 1));
}
for(it = items.begin(); it != items.end(); it++)
cout << it->first << " => " << it->second << endl;
}
int main() {
ifstream dataBaseFile("database3.txt", ios::in);
if(!dataBaseFile.good()) {
cout << "Failure while opening file";
exit(1);
}
countItems(dataBaseFile);
countTransactions(dataBaseFile);
dataBaseFile.close();
}
这是一个输出:
countTransation
5
countItems
std::ifstream
具有状态,这意味着应用于它的操作会影响未来操作的结果。例如,流具有读取位置。当您从流中读取某些内容时,读取位置会随着您读取的数据量而前进。
当您将dataBaseFile
传递给countItems
时,它会读取整个文件,并将读取位置一直推进到末尾。这是您调用countTransactions
时的位置保留的位置,因此它认为没有什么可读的。
将读取位置重置回零将解决此问题:
countItems(dataBaseFile);
dataBaseFile.clear(); // To clear out EOF
dataBaseFile.seekg(0, ios::beg);
countTransactions(dataBaseFile);
但是,这在性能方面并不理想,因为您最终会多次读取文件。当文件很小时,您最好将整个文件读入内存,例如读入std::vector<std::string>
,并使用内存中表示以获得更快的访问速度。