7

I have a source file file1 and a destination file file2, here I have to move content from file1 to file2.

So I have to do some validation first.

  1. I must check source file is existing or not? I can check using this:

    fp = fopen( argv[1],"r" );
    if ( fp == NULL )
    {
        printf( "Could not open source file\n" );
        exit(1);
    } 
    
  2. Then I have to check if the source file has any content or not? If it is empty, I have to throw some error message.

This is what I've tried until the moment.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    What OS are you working on? Windows? – Mike Nov 26 '12 at 13:48
  • `abnormal program termination` so an error? What's the message you're getting? – Mike Nov 26 '12 at 17:13
  • @mike: that is msg i am getting in command prompt –  Nov 26 '12 at 17:25
  • 1
    That's the whole message? The program compiles fine then blows up with that? Have you used a debugger to find out where? Did you validate that there's a valid value in `argv[1]` before using it? – Mike Nov 26 '12 at 17:27
  • this is the code.....fp = fopen(argv[1],"r"); if ( fp == NULL ) { printf( "Could not open sourse file : argv[1]\n"); exit(1); } else { fseek(fp, 0, SEEK_END); if (ftell(fp) == 0) { fputs("file is empty",fpout); } fseek(fp, 0, SEEK_SET); } –  Nov 26 '12 at 17:27
  • See also https://stackoverflow.com/q/28489691/1340631 – scai Sep 15 '21 at 09:29

7 Answers7

18

C version:

if (NULL != fp) {
    fseek (fp, 0, SEEK_END);
    size = ftell(fp);

    if (0 == size) {
        printf("file is empty\n");
    }
}

C++ version (stolen from here):

bool is_empty(std::ifstream& pFile)
{
    return pFile.peek() == std::ifstream::traits_type::eof();
}
Community
  • 1
  • 1
Oleksandr Kravchuk
  • 5,963
  • 1
  • 20
  • 31
  • 1
    I/O calls can fail, you should check that `fseek()` and `ftell()` succeed before relying on their results. – unwind Nov 26 '12 at 15:50
  • Absolutely! Every C programmer should understand this. I just wanted to simplify my example. – Oleksandr Kravchuk Nov 26 '12 at 15:56
  • Keep in mind that this only works for regular files. For special files from /proc/ or /sys/ `ftell()` will always report zero, even if they have content. – scai Sep 16 '21 at 06:46
7

You can do this without opening the file as well using the stat method.

#include <sys/stat.h>
#include <errno.h>

int main(int argc, char *argv[])
{

     struct stat stat_record;
     if(stat(argv[1], &stat_record))
         printf("%s", strerror(errno));
     else if(stat_record.st_size <= 1)
         printf("File is empty\n");
     else {
         // File is present and has data so do stuff...
     }

So if the file doesn't exist you'll hit the first if and get a message like: "No such file or directory"

If the file exists and is empty you'll get the second message "File is empty"

This functionality exists on both Linux and Windows, but on Win it's _stat. I haven't tested the windows code yet, but you can see examples of it here.

Mike
  • 47,263
  • 29
  • 113
  • 177
  • Keep in mind that this only works for regular files. For special files from /proc/ or /sys/ the size reported by stat will always be zero, even if they have content. – scai Sep 15 '21 at 09:25
5

Just look if there's a character to read

int c = fgetc(fp);
if (c == EOF) {
    /* file empty, error handling */
} else {
    ungetc(c, fp);
}
Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
  • This is the only answer that's strictly conforming, portable C code. Per the C standard, `fseek(..., SEEK_END)` on a binary stream is undefined behavior, and `ftell()` on a text stream returns "unspecified data" that can be used to return to the same position in the file - not a byte offset. – Andrew Henle May 15 '18 at 13:35
  • This is the only answer here that will work for special special files from /proc/ and /sys/. `stat()` and `ftell()` don't work as expected for these files. – scai Sep 16 '21 at 06:47
3
fseek(fp, 0, SEEK_END); // goto end of file
if (ftell(fp) == 0)
 {
      //file empty
 }
fseek(fp, 0, SEEK_SET); // goto begin of file
// etc;

reference for ftell and example

reference for fseek and example

Ivan Ignatiev
  • 1,023
  • 5
  • 15
2

You can use fseek using SEEK_END and then ftell to get the size of a file in bytes.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176
0

you can check if the file size > 0

after your code of checking file exist (before you close the file) you add the following code

   size = 0
    if(fp!=NULL)
    {
        fseek (fp, 0, SEEK_END);

        size = ftell (fp);
        rewind(fp);

    }
    if (size==0)
    {
      // print your error message here
     }
MOHAMED
  • 41,599
  • 58
  • 163
  • 268
0

It is painful to open the data and count each byte of the file. It is better to ask to the operating system to give you details about the files you want to used. The API relies depends on your operating system as Mike previously said.

yageek
  • 4,115
  • 3
  • 30
  • 48