Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如果fclose未执行两次,则无法确定大小_C++_Fclose - Fatal编程技术网

C++ 如果fclose未执行两次,则无法确定大小

C++ 如果fclose未执行两次,则无法确定大小,c++,fclose,C++,Fclose,我创建了一个文件类,它是一种文件类型的包装器,并添加了一些方法 这是我的文件类的代码: #include <Fs/File.h> File::File(Path& p): m_path(p), m_openned(false) { } int File::open(const string& mode) { m_f = new FILE; fopen(m_path, mode.c_str()); if

我创建了一个文件类,它是一种文件类型的包装器,并添加了一些方法

这是我的文件类的代码:

          #include <Fs/File.h>



File::File(Path& p):
    m_path(p),
    m_openned(false)
{
}

int File::open(const string& mode)
{
    m_f = new FILE;
    fopen(m_path, mode.c_str());
    if (m_f == NULL)
    {
        m_openned = false;
        return -1;
    }
    m_openned = true;
    return 0;
}

bool File::exists()
{
    FILE* file;

    if (file = fopen(m_path, "r"))
    {
        fclose(file);
        return true;
    }

    fclose(file);
    return false;
}

int File::flush(){
    return fflush(m_f);
}

int File::remove()
{
    return ::remove(m_path);
}

int File::close()
{
    if (isOpenned())
    {
        m_openned = false;
        return fclose(m_f);
    }

    return 0;
}

long File::getSize()
{
    struct stat file_status;
    if(!this->exists())
        return -1;
    if (stat(m_path, &file_status) < 0)
    {
        return -1;
    }

    return file_status.st_size;
}

FileMode File::getMode()
{
    struct stat file_status;

    if (stat(m_path, &file_status) < 0)
    {
        return FileMode(-1);
    }

    return FileMode(file_status.st_mode);
}



Path File::getPath()
{
    return m_path;
}


bool File::isOpenned()
{
    return m_openned;
}


int File::setMode(FileMode& mode)
{
    return chmod(m_path, mode);
}

int File::renameTo(File& f)
{
    if (f.exists() || !this->exists())
        return -1;

    return rename( m_path , f.getPath());
}

int File::copyTo(File& to)
{
    char ch;
    this->close();
    this->open(FileTypes::READ);
    to.close();
    to.open(FileTypes::WRITE);

    while (!this->eof())
    {
        ch = this->readc();

        if (ch == -1)
            return 0;

        if (!to.eof())
            to.writec(ch);
    }

    if (this->close() < 0)
    {
        return -1;
    }

    if (to.close() < 0)
    {
        return -1;
    }

    return 0;
}

int File::readc()
{
    if (!isOpenned())
        return FileTypes::ENDOFFILE;

    char c = fgetc(m_f);

    if (ferror(m_f))
    {
        return FileTypes::ENDOFFILE;
    }

    return c;
}

int File::writec(char c)
{
    if (!isOpenned())
        return -1;

    fputc(c, m_f);

    if (ferror(m_f))
    {
        return FileTypes::ENDOFFILE;
    }

    return 0;
}

bool File::eof()
{
    if (!isOpenned())
        return true;

    return feof(m_f);
}
#包括
文件::文件(路径和路径):
m_路(p),
m_已打开(错误)
{
}
int文件::打开(常量字符串和模式)
{
m_f=新文件;
fopen(m_路径,mode.c_str());
如果(m_f==NULL)
{
m_opened=假;
返回-1;
}
m_openned=真;
返回0;
}
bool文件::exists()
{
文件*文件;
if(file=fopen(m_路径,“r”))
{
fclose(文件);
返回true;
}
fclose(文件);
返回false;
}
int文件::flush(){
返回fflush(m_f);
}
int File::remove()
{
return::remove(m_路径);
}
int文件::close()
{
if(等间距()
{
m_opened=假;
返回fclose(m_f);
}
返回0;
}
长文件::getSize()
{
结构统计文件的状态;
如果(!this->exists())
返回-1;
if(stat(m_路径和文件状态)<0)
{
返回-1;
}
返回文件\u status.st\u size;
}
FileMode文件::getMode()
{
结构统计文件的状态;
if(stat(m_路径和文件状态)<0)
{
返回文件模式(-1);
}
返回文件模式(文件状态.st\u模式);
}
路径文件::getPath()
{
返回m_路径;
}
bool文件::isOpenned()
{
返回打开的m_;
}
int File::setMode(FileMode和mode)
{
返回chmod(m_路径,模式);
}
int File::重命名为(文件(&f)
{
如果(f.exists()| |!this->exists())
返回-1;
返回rename(m_path,f.getPath());
}
int File::copyTo(文件和目标)
{
char ch;
此->关闭();
此->打开(文件类型::读取);
to.close();
打开(文件类型::写入);
而(!this->eof())
{
ch=此->readc();
如果(ch==-1)
返回0;
如果(!to.eof())
书面形式(ch);
}
如果(此->关闭()<0)
{
返回-1;
}
if(to.close()<0)
{
返回-1;
}
返回0;
}
int文件::readc()
{
如果(!isOpenned())
返回文件类型::ENDOFFILE;
char c=fgetc(m_f);
if(ferror(m_f))
{
返回文件类型::ENDOFFILE;
}
返回c;
}
int File::writec(char c)
{
如果(!isOpenned())
返回-1;
fputc(c,m_f);
if(ferror(m_f))
{
返回文件类型::ENDOFFILE;
}
返回0;
}
bool文件::eof()
{
如果(!isOpenned())
返回true;
返回feof(m_f);
}
我做了一些测试,我有一种问题

            Path p1("test.txt");
    Path p2("temp.txt");

    File f1(p1);
    File f2(p2);

    assert(f1.open(FileTypes::READ) == 0);
    assert(f1.exists() == true);
    assert(f1.close() == 0);

    cout<<"Mode of f1 "<<f1.getMode().getStringMode()<<endl;
    cout<<"Path of f1 "<<f1.getPath().getAbsolutePath()<<endl;
    cout<<"Size of f1 "<<f1.getSize()<<endl;

    assert(f2.exists() == false);
    assert(f1.copyTo(f2) == 0);
            //#####################################
             // If I comment f2.close() the                              
             // assert(f1.getSize() == f2.getSize()) test fails and                  
             // f2.getSize() == 0
             ##########################################
    f2.close();

    assert(f2.exists() == true);
    assert(f1.getSize() == f2.getSize());
路径p1(“test.txt”); 路径p2(“temp.txt”); 文件f1(p1); 文件f2(p2); 断言(f1.open(FileTypes::READ)==0); 断言(f1.exists()==true); 断言(f1.close()==0);
cout
fclose
刷新流。我的猜测是,在不关闭文件的情况下,流尚未完全写入,因此大小不同。考虑添加<代码> FFLUH(to);
copyTo
方法的末尾,以确保所有内容都已写入。

文件::copyTo
中:

    if (ch == -1)
        return 0;

您在未正确关闭文件的情况下跳出函数。当目标文件未关闭时,其内容可能不会发送到操作系统,操作系统随后会报告虚假的文件大小。

copyTo函数有多个出口,但无法确保您确实关闭该文件。在我看来,您可能会提前退出copyTo功能,并且预期的关闭没有执行

 while (!this->eof())
{
    ch = this->readc();

    if (ch == -1)
        return 0;

    if (!to.eof())
        to.writec(ch);
}

当您点击文件的结尾时,您将得到EOF,在我的OS(Windows)中它是-1,这会导致您返回0,跳过关闭调用。

总是有BooSo.FixSeal.为C++ +Tr2提出的。在<代码> Copyto< /C>中,如果<代码> ->()(代码)>失败,您永远不会调用<代码> to .Cutely()/<代码>。不过,这可能不是问题的原因。您确定总是在
copyTo
中找到
关闭
?这里似乎有许多
return
语句。