【问题标题】:Checking for an empty file in C++在 C++ 中检查空文件
【发布时间】:2010-03-06 00:48:35
【问题描述】:

有没有一种简单的方法来检查文件是否为空。就像你将一个文件传递给一个函数并且你意识到它是空的,然后你马上关闭它?谢谢。

编辑,我尝试使用 fseek 方法,但我收到一条错误消息,提示“无法将 ifstream 转换为 FILE *”。

我的函数的参数是

myFunction(ifstream &inFile)

【问题讨论】:

  • 不能轻易从fstream 获取文件描述符,这太糟糕了。您可以在 Unix 上使用 fstat 轻松检查空文件。 :-P

标签: c++ eof


【解决方案1】:

也许类似于:

bool is_empty(std::ifstream& pFile)
{
    return pFile.peek() == std::ifstream::traits_type::eof();
}

又短又甜。


考虑到您的错误,其他答案使用 C 样式文件访问,您可以在其中获得具有特定功能的 FILE*

相反,你和我都在使用 C++ 流,因此不能使用这些函数。上面的代码以一种简单的方式工作:peek() 将查看流并返回而不删除下一个字符。如果到达文件末尾,则返回eof()。所以,我们只是在流中peek() 看看它是否是eof(),因为一个空文件没有什么可看的。

注意,如果文件从未打开过,这也会返回 true,这应该适用于您的情况。如果你不想这样:

std::ifstream file("filename");

if (!file)
{
    // file is not open
}

if (is_empty(file))
{
    // file is empty
}

// file is open and not empty

【讨论】:

  • 添加return pFile.tellg() > 0 || …不会太难
  • pFile.peek() == '\n' 不也能正常工作吗?
  • @ViktorStefanov 不,如果文件以空行开头怎么办?
【解决方案2】:

好的,所以这段代码应该适合你。我更改了名称以匹配您的参数。

inFile.seekg(0, ios::end);  
if (inFile.tellg() == 0) {    
  // ...do something with empty file...  
}

【讨论】:

  • 那么这到底是在做什么呢?它有效,但我想知道为什么。它是否在检查流的结尾并查看它是否等于 0?
【解决方案3】:

寻找到文件末尾并检查位置:

 fseek(fileDescriptor, 0, SEEK_END);
 if (ftell(fileDescriptor) == 0) {
     // file is empty...
 } else {
     // file is not empty, go back to the beginning:
     fseek(fileDescriptor, 0, SEEK_SET);
 }

如果您还没有打开文件,只需使用fstat 函数并直接检查文件大小。

【讨论】:

    【解决方案4】:
    char ch;
    FILE *f = fopen("file.txt", "r");
    
    if(fscanf(f,"%c",&ch)==EOF)
    {
        printf("File is Empty");
    }
    fclose(f);
    

    【讨论】:

    • 为什么要在 C++ 中使用这些 C 习语?
    【解决方案5】:

    使用这个: data.peek() != '\0'

    我一直在寻找一个小时,直到最后这有帮助!

    【讨论】:

      【解决方案6】:

      C++17 解决方案:

      #include <filesystem>
      
      const auto filepath = <path to file> (as a std::string or std::filesystem::path)
      
      auto isEmpty = (std::filesystem::file_size(filepath) == 0);
      

      假设您存储了文件路径位置,我认为您不能从 std::ifstream 对象中提取文件路径。

      【讨论】:

        【解决方案7】:
        pFile = fopen("file", "r");
        fseek (pFile, 0, SEEK_END);
        size=ftell (pFile);
        if (size) {
          fseek(pFile, 0, SEEK_SET);
          do something...
        }
        
        fclose(pFile)
        

        【讨论】:

        • 使用类似于“100110”的工具栏按钮格式化代码
        【解决方案8】:

        怎么样(虽然不是优雅的方式)

        int main( int argc, char* argv[] )
        {
            std::ifstream file;
            file.open("example.txt");
        
            bool isEmpty(true);
            std::string line;
        
            while( file >> line ) 
                isEmpty = false;
        
                std::cout << isEmpty << std::endl;
        }
        

        【讨论】:

        • 很公平。它比 user4471014 稍微好一点(由于是实际 C++,而不是 C),但仍然完全浪费和次优。
        • @LightnessRacesinOrbit,你是对的,但是不需要遍历文件的所有行。一旦检测到第一行并将isEmpty 设置为false,就可以停止while 循环。如果这可以增强代码。
        • 我可以理解这段代码不是最理想的,但为什么它是浪费的? OP 没有要求或寻找足够或如此优化的代码。
        • (a) 这很浪费,因为您正在提取永远不会使用的数据。读那些字符是没有意义的。 (b) 仅仅因为 OP 没有竭尽全力要求“优化”代码并不意味着我们应该竭尽全力提供相反的代码。 :)
        【解决方案9】:

        当文件为空时,如果它为空,tellg 将为您提供值 0,因此请专注于此,这是查找空文件的最简单方法,如果您只是创建文件,它将为您提供 -1。

        outfile.seekg(0,ios::end);
        if(file.tellg()<1){
          //empty
        }else{
          file.clear(); // clear all flags(eof)
          file.seekg(0,ios::beg);//reset to front
          //not empty
        }
        

        【讨论】:

          【解决方案10】:
          if (nfile.eof()) // Prompt data from the Priming read:
              nfile >> CODE >> QTY >> PRICE;
          else
          {
              /*used to check that the file is not empty*/
              ofile << "empty file!!" << endl;
              return 1;
          }
          

          【讨论】:

          • 虽然这可能会为 OP 的问题提供解决方案,但没有对代码的解释。
          猜你喜欢
          • 1970-01-01
          • 2011-05-03
          • 2015-07-19
          • 1970-01-01
          • 1970-01-01
          • 2013-02-24
          • 2016-10-25
          • 2015-04-13
          • 2011-01-07
          相关资源
          最近更新 更多