我有一个非常简单的代码:
void LookupName( string tname ){ //Checks for name in records.txt and enters it if it does not exist
//Variables
string fname; //Used to store the name
string throwaway; //Used to dispose of extra data
bool found = false; //Used to track if a name is found in the file
//objects
fstream file ( STATS_FILE ); //Open the file
if (file.is_open()) {
while ( !file.eof() ) {
getline (file, fname, DELIM); //Fill name
getline (file, throwaway, '\n'); //throw away rest of line
cout << "Found: " << fname << " tname: " << tname << '\n';
Pause();
if ( fname == tname ) { //Otherwise, continue
cout << "Found: " << fname << " tname: " << tname << '\n';
Pause();
found = true;
}
}
if ( found == false ) { //if the name is not found
//Reopen the file so that we can write to it
file.close();
file.open( STATS_FILE, fstream::in | fstream::out | fstream::app );
cout << "Not found" <<endl;
Pause();
file << tname << ",0,0\n"; //Add it to the file with 0 wins and losses
}
//Cleanup
file.close();
}
}
这样可行,但如果您在检查名称是否找到时在底部注意到,我必须关闭并重新打开该文件。
以下内容因某些原因无效:
void LookupName( string tname ){ //Checks for name in records.txt and enters it if it does not exist
//Variables
string fname; //Used to store the name
string throwaway; //Used to dispose of extra data
bool found = false; //Used to track if a name is found in the file
//objects
fstream file ( STATS_FILE, fstream::in | fstream::out | fstream::app ); //Open the file
if (file.is_open()) {
while ( !file.eof() ) {
getline (file, fname, DELIM); //Fill name
getline (file, throwaway, '\n'); //throw away rest of line
cout << "Found: " << fname << " tname: " << tname << '\n';
Pause();
if ( fname == tname ) { //Otherwise, continue
cout << "Found: " << fname << " tname: " << tname << '\n';
Pause();
found = true;
}
}
if ( found == false ) { //if the name is not found
cout << "Not found" <<endl;
Pause();
file << tname << ",0,0\n"; //Add it to the file with 0 wins and losses
}
//Cleanup
file.close();
}
}
我很想知道为什么它在第二个例子中不起作用,因为用正确的标志打开文件只有一次效率似乎更高效,做我需要做的事情并关闭它。
我有一种感觉这可能与光标的位置有关,我试图使用像file.seekg(0)和file.seekg(0,ios_base :: beg)这样的东西,但它们没有似乎像宣传的那样工作(或者我只是误解了广告)。
任何意见都会受到赞赏。
编辑:couts用于调试。
编辑2:我想我应该再强调一下这个问题。
问题是第二个示例没有写入第一个示例所在的文件。我理解可能有一些关于!file.eof()条件的问题,但是在这个例子中我并不关心它是否会运行一个额外的时间,因为它不会对结果产生负面影响(另外,正在读取的文本文件)已正确格式化,以便不会发生这种情况。)
编辑3: 我创建了一个非常小的程序:
//Testing bs
fstream file("Test.txt", fstream::in | fstream:: out | fstream::app );
string temp;
//ClearScreen
system(CLEAR_SCREEN);
file << "Line one\n";
getline(file, temp);
file << temp;
file << "Line two\n";
Pause();
return Menu;
只有第一行写入文件。我打赌getline正在改变流的模式,这就是为什么它在后面是不可写的。
最终编辑: 经过一系列研究后,似乎在上述情况下,重新打开文件是最佳解决方案。最终,问题在于使用getline()和file.getline()。我必须重写程序的1000行太多,才能“正确”地完成它。故事的道德启示?如果您遇到此问题,请花一些时间研究istream::getline和getline(string)之间的区别,并学会确定何时使用哪个,这样您就不会遇到这种情况。幸运的是,现在我没有必要修复它,但未来可能会有其他人使用它。
答案 0 :(得分:0)
我不能给你一个明确的答案,但根据推论,我可以给你一个很好的主意。
您正在使用fstream
(文件流),其实例用于处理文件。如果您查看fstream.open
(link)的文档,请注意第二个参数已设置为默认情况下输入或输出到一个文件。请注意,默认值是一个或另一个。这意味着在打开文件时,您无法假定该文件存在。更重要的是,由于您可能从fstream
的角度输入文件,因此不应该假设如果文件不存在,则应该创建它。
另一种思考方式:我将假设您熟悉ifstream
(输入文件流)和ofstream
(输出文件流),这些内容通常在前面的C ++教程/指南中介绍过比fstream
。如果您查看ifstream
(link)和ofstream
(link)的文档,您会发现它们都来自{{1} }。现在请记住,当您调用fstream
时,如果该文件不存在,则不会创建它 - 而是设置了failbit。相反,当您致电ifstream.open
时,如果该文件不存在,则
现在,由于ofstream.open
和ifstream
都来自ofstream
,我们有两种可能性:
fstream
直接从ofstream.open
派生(即它没有扩展功能),我们可以合理地期望fstream.open
创建文件,因为它最初不存在fstream.open
直接来自ifstream.open
,我们可以合理地期望fstream.open
不来创建文件,因为它首先不存在< / LI>
醇>
不言而喻,这两者都不可能是真的; fstream.open
和ofstream.open
不能同时来自同一件事,但他们所做的事情却有所不同; ifstream.open
不能做和不做某事。
如果您考虑一下,第二种选择更有可能,这就是原因:如果fstream.open
不直接来自ofstream.open
,那么它所要做的只是添加一个额外的步骤,如果文件不存在则创建文件,并重置failbit。通过调用父类的fstream.open
函数可以实现上述所有行为。另一方面,如果open
没有直接派生自ifstream.open
(暗示fstream.open
创建文件,因为它首先不存在),fstream.open
必须完全重新实施;否则将无法跳过创建不存在的文件的步骤。
因为拥有一个重新实现的功能比使用一个简单添加内容的不同功能更有效,所以ifstream.open
更不可能创建/打开文件已经存在了。
我意识到这可能不是您问题的最终解决方案,但我认为这可以解释为什么您发布的第二个代码块不会(也不应该)起作用。当我看到你的第一个代码块(你说它工作)时,我不完全确定它是什么使它工作,但我猜它与你在开放模式参数中添加fstream.open
有关| fstream::append
。
我希望这会有所帮助。