Continuing my previous article Understanding File Handling Functions in C, here in this article let us focus on functions like : fread() // read a chunk of data from file fwrite() // Write a chunk of data to file feof() // Check for end of file indicator ferror() // Check for error indicator for this stream fseek() // Seek to a particular position in file fileno() // Return an integer file descriptor fdopen() // associate a stream with existing file descriptor Lets understand these functions in two sets. Understanding fread(), fwrite(), feof() and ferror() Here is a code that uses the above three functions : Code: #include<stdio.h> #include<string.h> int main(void) { FILE *fd = NULL; char buff[512]; unsigned int nread = 0; memset(buff, '\0', sizeof(buff)); // Open a file 'ps.txt' in r+ mode ie a mode that // supports both reading and writing. fd = fopen("ps.txt","r+"); if(NULL == fd) // Check for error { printf("\n File opening failed\n"); return 1; } nread = 50; // Hard code the number of elements to 50 // fread() reads 'nread' elements of data, each being 1 byte long // from 'fd' file descriptor and copies the chink of data read // from file to the buffer 'buff'. // It returns number of items successfully read, like in this case // if the call is successful, it should return the value of 'nread'. // So, here we have tested the return of this function against the // 'nread' variable to judge whether the API failed or passed. while( nread == fread(buff, 1, nread, fd) ) { printf("\n THE %d BYTES READ ARE : \n<<<%s>>>\n\n\n", (int)nread, buff); } // This function is used to test the end of file indicator for a file // What happens is that, through any kind of read operation in the file // if we try to read past the end of file then end-of-file indicator is // set. After this anytime if we call feof(), it will return a non-zero // value signifying that end of file has been reached. If this API returns // zero then that means end of file has not yet been reached. NOTE that // this API works only if a read attempt past the end of file has been made // For example, for a 50 byte file, merely reading all the 50 bytes will not // set the end-of-file indicator. An attempt to read past should have been // made before making a call to feof(). This function takes file descriptor // as an argument. if(feof(fd)) { printf("\n Seems like end of file was reached\n"); } // IF while performing any type of file related operations using file related // functions, an error occurs then error indicator is set. This error indicator // can be examined by this function so that code may come to know that an error // has occurred. This function also takes file descriptor as an argument. else if(ferror(fd)) { printf("\n Some errors on this stream occurred\n"); } // Reset the buffer with NULLs memset(buff, '\0', sizeof(buff)); // Copy a hard coded string to buff so that we can write this string in file. strncpy(buff, "SomeThing to be written to file\n", strlen("SomeThing to be written to file\n")); // fwrite() is used to write a chunk of data to file. To be specific, it writes // 1 element of size return by strlen() from 'buff' to the file using file // descriptor 'fd'. As fread(), this function also returns the number of items // successfully written, which in this case is '1'. if(1 == fwrite(buff, strlen("SomeThing to be written to file\n"), 1, fd)) { printf("\n File written successfully\n"); } else { printf("\n File writing failed through fwrite()\n"); return 1; } return 0; } The code above is self explained. I have written all the explanations as comments in the code so that whosoever copies the code for practice, automatically takes away the explanation part too. Now lets see the output Output Before looking at the output, lets look at the ps.txt first : Code: UID PID PPID C STIME TTY TIME CMD root 1 0 0 05:29 ? 00:00:00 /sbin/init root 2 0 0 05:29 ? 00:00:00 [kthreadd] root 3 2 0 05:29 ? 00:00:00 [migration/0] root 4 2 0 05:29 ? 00:00:00 [ksoftirqd/0] root 5 2 0 05:29 ? 00:00:00 [watchdog/0] root 6 2 0 05:29 ? 00:00:00 [migration/1] root 7 2 0 05:29 ? 00:00:00 [ksoftirqd/1] root 8 2 0 05:29 ? 00:00:00 [watchdog/1] root 9 2 0 05:29 ? 00:00:00 [events/0] ... ... ... ... himanshu 1993 1 0 05:31 ? 00:00:00 /bin/sh /usr/lib/firefox-3.6.3/firefox himanshu 1998 1993 0 05:31 ? 00:00:00 /bin/sh /usr/lib/firefox-3.6.3/run-mozilla.sh /usr/lib/firefox-3.6.3/firefox-bin himanshu 2002 1998 20 05:31 ? 00:07:33 /usr/lib/firefox-3.6.3/firefox-bin himanshu 2090 1 1 05:34 ? 00:00:29 gedit /home/himanshu/Desktop/articles/go4expert/Nov2011/name_changer.txt himanshu 2102 1966 0 05:38 pts/1 00:00:00 bash himanshu 2500 1966 2 06:09 pts/0 00:00:00 bash himanshu 2515 2102 0 06:09 pts/1 00:00:00 ./namepid himanshu 2516 2515 0 06:09 pts/1 00:00:00 sh -c /bin/sh -c 'ps -aef > ps.txt' himanshu 2517 2516 0 06:09 pts/1 00:00:00 /bin/sh -c ps -aef > ps.txt himanshu 2518 2517 0 06:09 pts/1 00:00:00 ps -aef Now when I executed the code, I got : Code: ... ... ... THE 50 BYTES READ ARE : <<< 2500 1966 2 06:09 pts/0 00:00:00 bash himan>>> THE 50 BYTES READ ARE : <<<shu 2515 2102 0 06:09 pts/1 00:00:00 ./namep>>> THE 50 BYTES READ ARE : <<<id himanshu 2516 2515 0 06:09 pts/1 00:00:00>>> THE 50 BYTES READ ARE : <<< sh -c /bin/sh -c 'ps -aef > ps.txt' himanshu 251>>> THE 50 BYTES READ ARE : <<<7 2516 0 06:09 pts/1 00:00:00 /bin/sh -c ps ->>> THE 50 BYTES READ ARE : <<<aef > ps.txt himanshu 2518 2517 0 06:09 pts/1 >>> Seems like end of file was reached File written successfully SO we see that the code successfully read all the 50 bytes lines from the file ps.txt and printed them. After reading the complete file, it was able to detect the end of file and then wrote something to it. If you refer the code, this is what we wanted our code to do. Now lets have a quick look at what got written to file as last line of output shown above says that something got written to file. Lets check ps.txt : Code: ... ... ... himanshu 1966 1 0 05:31 ? 00:00:01 /usr/bin/gnome-terminal -x /bin/sh -c '/home/himanshu/Desktop/Reliance.sh' himanshu 1967 1966 0 05:31 ? 00:00:00 gnome-pty-helper himanshu 1993 1 0 05:31 ? 00:00:00 /bin/sh /usr/lib/firefox-3.6.3/firefox himanshu 1998 1993 0 05:31 ? 00:00:00 /bin/sh /usr/lib/firefox-3.6.3/run-mozilla.sh /usr/lib/firefox-3.6.3/firefox-bin himanshu 2002 1998 20 05:31 ? 00:07:33 /usr/lib/firefox-3.6.3/firefox-bin himanshu 2090 1 1 05:34 ? 00:00:29 gedit /home/himanshu/Desktop/articles/go4expert/Nov2011/name_changer.txt himanshu 2102 1966 0 05:38 pts/1 00:00:00 bash himanshu 2500 1966 2 06:09 pts/0 00:00:00 bash himanshu 2515 2102 0 06:09 pts/1 00:00:00 ./namepid himanshu 2516 2515 0 06:09 pts/1 00:00:00 sh -c /bin/sh -c 'ps -aef > ps.txt' himanshu 2517 2516 0 06:09 pts/1 00:00:00 /bin/sh -c ps -aef > ps.txt himanshu 2518 2517 0 06:09 pts/1 00:00:00 ps -aef SomeThing to be written to file Just see the last line of ps.txt above, this is what we were trying to write through the code. We see that the string "SomeThing to be written to file" was successfully written to file. Conclusion To conclude, in this article, we understood the APIs like fread(), fwrite, feof() etc and learned how to use them practically in code. Stay tuned for more!!!