C++ C++;文件I/O必须重新打开文件才能写入吗?

C++ C++;文件I/O必须重新打开文件才能写入吗?,c++,C++,我有一个非常简单的代码: 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 trac

我有一个非常简单的代码:

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){//检查records.txt中的名称,如果不存在,则输入该名称
//变数
字符串fname;//用于存储名称
string throwaway;//用于处理额外数据
bool found=false;//用于跟踪是否在文件中找到名称
//物体
fstream文件(STATS_文件);//打开文件
if(file.is_open()){
而(!file.eof()){
getline(文件、fname、DELIM);//填充名称
getline(文件,一次性,'\n');//丢弃行的其余部分

我不能给你一个明确的答案,但我可以根据推论给你一个相当好的主意

您使用的是
fstream
(文件流),其实例用于处理文件。如果您查看
fstream的文档,请打开
(),请注意,第二个参数设置为,默认情况下,它将输入或输出到文件。请注意,默认值为一个或另一个。这意味着您无法在打开文件时假设文件存在。更重要的是,由于您可能是从文件输入的,因此从对于
fstream
,不应假定如果文件不存在,则应创建该文件

另一种方法:假设您熟悉 IfStase(输入文件流)和 <流>代码>(输出文件流),这在C++教程/指南中比在 fStult>代码中一般介绍得更早。对于流的

(),您会注意到它们都源自
fstream
。现在请记住,当您调用
ifstream.open
时,如果文件不存在,则不会创建该文件,而是设置了故障位。相反,当您调用stream.open
时,如果文件不存在,则会创建该文件

现在,由于流的
ifstream
都源自
fstream
,我们有两种可能性:

  • ofstream.open
    直接派生自
    fstream.open
    (即它没有扩展的功能),我们可以合理地期望
    fstream.open
    创建文件,因为它一开始并不存在
  • ifstream.open
    直接派生自
    fstream.open
    ,我们可以合理地期望
    fstream.open
    不创建文件,因为它最初并不存在
  • 不用说,这两个都不可能是真的;
    ofstream.open
    ifstream.open
    不能都来自同一事物,但它们的作用却不同;
    fstream.open
    不能同时做和不做某事

    如果您仔细想想,第二个选项更可能出现,原因如下:如果stream.open的
    不是直接从fstream.open派生的,那么它所要做的就是添加一个额外的步骤,在这个步骤中,如果文件不存在,它将创建该文件,并重置故障位。通过调用
    open,可以实现前面的所有行为
    父类的函数。另一方面,如果
    ifstream.open
    不是直接从
    fstream.open
    派生的(这意味着
    fstream.open
    创建了文件,假设它一开始不存在),
    ifstream.open
    必须是完整的重新实现;否则将无法跳过创建不存在文件的步骤

    由于重新实现的函数要比简单添加内容的函数效率低,因此如果文件不存在,
    fstream.open
    很可能不会创建/打开文件

    我意识到这可能不是您问题的最终解决方案,但我认为这应该可以解释为什么您发布的第二个代码块不会(也不应该)工作我不完全确定它是如何工作的,但我猜这与您在
    fstream.open的open mode参数中添加了
    |fstream::append
    有关


    我希望这会有所帮助。

    您可能想先阅读@TonyD大量的好信息,谢谢;但是,这与问题完全无关。我不会标记您的评论,但我也不会投票,不管它值多少钱。改为以二进制模式打开该文件,然后seekg将“如广告所示”工作@我相信你是正确的;但是,这似乎不是解决整个问题的方法。谢谢你的提示。@Toby-使用了像
    while(!file.eof())这样的错误代码
    ,在修复之前,您不能期望其余部分正常工作…我很抱歉,但您声称第一个有效的原因似乎与第二个无效的原因完全相同。它们都有fstream::app。唯一的区别是模式出现的位置。第一个出现在我已经运行了整个文件之后,第二个出现在前面。据我所知(它没有在cplusplus.com上列出)fstream的默认值是ios_base::in | ios_base:;out,意思是在它的默认状态下,我应该能够对文件进行写入和读取。对-但只有在文件已经存在的情况下。如果它还不存在,它就不会创建文件-这是我的文章的重点。我只提到了
    fstream::append
    ,因为我认为你使用了这可能是某些东西正常工作而其他东西不正常的原因。但正如您所指出的,您在第二个代码块中打开文件时也有它。因此,可能不是这样。即使您打开的文件存在,第二个代码块是否也无法运行?另一个想法-在第二个代码块中,您在(!in.eof())
    在尝试
    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();
    } 
    }
    
       //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;