22858 total geeks with 3297 solutions
Recent challengers:
best bread maker
 Welcome, you are an anonymous user! [register] [login] Get a yourname@osix.net email address 

Articles

GEEK

User's box
Username:
Password:

Forgot password?
New account

Shoutbox
sefo
anilg, new comments are deleted automaticall y because of some abuse recently
anilg
this is plain wierd. I submitted comments twice to article 950, and they dont seem to be there. Something wrong with the comment code?
CodeX
shout-boxes in general are old + the staff thing happened to everyone after an issue 2 months ago
anilg
/me is no longer staff :(
anilg
Also, osix's shoutbox predated twitter. Heh.

Donate
Donate and help us fund new challenges
Donate!
Due Date: Jul 31
July Goal: $40.00
Gross: $0.00
Net Balance: $0.00
Left to go: $40.00
Contributors


News Feeds
The Register
UK.gov sticks to IE
6 cos it"s more
"cost effective",
innit
T-Mobile UK pumps
out the iPhone 4
Polaroid 300
instant print
camera
NatWest dumps O2
Money
YouTube ups video
time limit
Alleged expenses
fiddlers to face
justice
Nude trampolinist
bounces free from
court
Nexus One phone
rockets to 28,000ft
UK.gov drops £6m on
Google
Fake Firefox update
used to sling
scareware
Slashdot
British ISPs Favour
Well-Connected
Customers
"Bizarre"
Nanobubbles Found
In Strained
Graphene
1-in-1,000 Chance
of Asteroid Impact
In
...
2182?
2 Chinese ISPs
Serve 20% of World
Broadband Users
World"s Fastest
Hybrid OK"d For
Production
Sometimes It"s OK
To Steal My Games
Thermoelectrics
Could Let You Feel
the Heat In Games
KDE SC 4.7 May Use
OpenGL 3 For
Compositing
Perl 6, Early, With
Rakudo Star
Internal Costs Per
Gigabyte —
What Do You Pay?
Article viewer

C File Handling II: Advanced File Handling with C



Written by:noimnot
Published by:Nightscript
Published on:2005-11-29 09:02:14
Topic:C
Search OSI about C.More articles by noimnot.
 viewed 72165 times send this article printer friendly

Digg this!
    Rate this article :
File Handling in C is in fact a simple task. But this does not mean youre limited to do simple things.

Part one showed you how to open/read from/write to and close files. This issue will deal with more complex functions and algorithms.

  • File-Error Handling

    The function int ferror(FILE *fp); returns true if the last operation performed on fp caused an error, otherwise it returns false.

    An example on how to use ferror():

       ch=getc(fp);
       if(ferror(fp)) f_err_report(ERR_READ);


    getc(fp) reads a char from the file associated to fp. If an error occured with getc(fp), ferror(fp) would return true and call f_err_report(ERR_READ); (which reports the error to stdout and exits the program).

    Full-Source:

    1:  // file error handling
    2:  #include <stdio.h>
    3:  
    4:  #define ERR_OPEN_1 11
    5:  #define ERR_OPEN_2 12
    6:  #define ERR_READ 13
    7:  #define ERR_WRITE 14
    8:  
    9:  int f_err_report(int mode) {
    10:   if(mode==ERR_OPEN_1) printf("error opening file1n");
    11:   if(mode==ERR_OPEN_2) printf("error opening file2n");
    12:   else if(mode==ERR_READ) printf("error reading from file");
    13:   else if(mode==ERR_WRITE) printf("error writing to file");
    14:   exit(1);
    15:  }
    16:  
    17:  int main(int argc, char *argv[])
    18:  {
    19:   if(argc<3) { printf("%s <file1> <file2>n",argv[0]); exit(1); }
    20:   char ch;
    21:   FILE *fp,*fp2;
    22:   if((fp=fopen(argv[1],"r"))==NULL) f_err_report(ERR_OPEN_1);
    23:   if((fp2=fopen(argv[2],"w"))==NULL) f_err_report(ERR_OPEN_2);
    24:   while(!feof(fp)) {
    25:    ch=getc(fp);
    26:    if(ferror(fp)) f_err_report(ERR_READ);
    27:    if(!feof(fp))
    28:    putc(ch,fp2);
    29:    else break;
    30:    if(ferror(fp)) f_err_report(ERR_WRITE);
    31:   }
    32:   fclose(fp);
    33:   fclose(fp2);
    34:   return 0;
    35:  }
    36:  


    Youre strongly encouraged to use ferror() whenever you perform operations on a FILE pointer, since errors that "could" arise from such a source may hardly be identified if you dont report them.

  • Removing files from the filesystem

    Deleting files is done useing int remove(const char *filename); which returns false on success or int>0 on errors.
    Since remove() returns 0 on success an if-statement suffices to do the "error-checking".

    An example on how to use remove():

       if(remove(argv[1])) { printf("error deleting file: %sn",argv[1]); exit(1); }


    In the above example the function remove() is called with a pointer to the first argument given to the program as a parameter. If it does not return false, the error is reported and the program terminates.

    Full-Source:

    1:  // deleting a file
    2:  #include <stdio.h>
    3:  
    4:  int main(int argc, char *argv[])
    5:  {
    6:   if(argc<2) { printf("%s <filename>n",argv[0]); exit(1); }
    7:   char ch;
    8:   printf("are you sure you want to delete regular file %s? (y/n): ",argv[1]);
    9:   ch=getc(stdin);
    10:   if(ch=='y') {
    11:    if(remove(argv[1])) { printf("error deleting file: %sn",argv[1]); exit(1); }
    12:   } else printf("abortedn");
    13:   return 0;
    14:  }
    15:  


  • fread() & fwrite()

    To read in datatypes with a size of more than 1 byte from a binary file (must be opened in binary access-mode), the C-Standard supplies the fread() and fwrite() functions.

  • fread()

    size_t fread(void *ptr, size_t num_bytes, size_t count, FILE *stream);

    This function reads count elements of size num_bytes from a FILE * (filepointer) stream, and copies it to the memory as pointed to by ptr.

  • fwrite()

    fwrite() works just the other way around, meaning ptr is the place in memory from where to copy count elements of size num_bytes to a FILE * stream.

    size_t fwrite(const void *ptr,size_t num_bytes,size_t count,FILE *stream);

    An example on how to use fread() & fwrite():

      if(fread(p,sizeof(char)*5,1,fp)!=1) {
       if(feof(fp)) break;
       f_err_report(ERR_READ);
      }
      if(fwrite(p,sizeof(char)*5,1,fp2)!=1) {
       if(feof(fp)) break;
       f_err_report(ERR_WRITE);
      }


    The above code reads 1 array of 5 chars from the FILE * fp and copies it to memory starting at p and vicaverse (1 times the size of 5 char of p to fp2. feof() is called because both functions return 1 on failure and EOF (End of File), and since we want to know if the operation failed or just hit the end of the file we check before "creating" an error.

    Full-Source:

    1:  // fread & fwrite example
    2:  #include <stdio.h>
    3:  
    4:  #define ERR_OPEN_1 11
    5:  #define ERR_OPEN_2 12
    6:  #define ERR_READ 13
    7:  #define ERR_WRITE 14
    8:  
    9:  #define TEXTSIZE 100
    10:  
    11:  int f_err_report(int mode) {
    12:   //...
    13:  }
    14:  
    15:  int main(int argc, char *argv[])
    16:  {
    17:   if(argc<3) { printf("%s <file1> <file2>n",argv[0]); exit(1); }
    18:   char *p;
    19:   p=(char *)malloc(sizeof(char)*TEXTSIZE);
    20:   FILE *fp,*fp2;
    21:   if((fp=fopen(argv[1],"r"))==NULL) f_err_report(ERR_OPEN_1);
    22:   if((fp2=fopen(argv[2],"w"))==NULL) f_err_report(ERR_OPEN_2);
    23:   while(!feof(fp)) {
    24:    if(fread(p,sizeof(char)*5,1,fp)!=1) {
    25:     if(feof(fp)) break;
    26:     f_err_report(ERR_READ);
    27:    }
    28:    if(fwrite(p,sizeof(char)*5,1,fp2)!=1) {
    29:     if(feof(fp)) break;
    30:     f_err_report(ERR_WRITE);
    31:    }
    32:   }
    33:   fclose(fp);
    34:   fclose(fp2);
    35:   return 0;
    36:  }
    37:  


  • Getting the filepointers position indicator

    If you open up a file-descriptor (FILE * or filepointer) in C, a stream is created inside the memory, containing the first some bytes of the file. If an operation is performed on that FILE *, the position-indicator is beeing increased, which copies some more bytes from the file to memory (inside the stream you opened. (this happens in background)). The following operation will therefore automatically read from a "later" position inside the file and also move the position indicator towards the end of the file.
    To find the (memory-)address of the current FILE *'s (filepointer's) position, the function long ftell(FILE *fp) is called, returning the adress of the current position inside the file associated to fp or -1 on error.

  • Moving the filepointers position indicator

    In cases one needs to find a certain position in a file or just skip some bytes that wont be needed, it is possible to move the FILE *'s postition indicator (The pointers position in the file).
    This is done useing the fseek() function, which is defined as: int fseek(FILE *fp,long numbytes,int origin); where fp is a valid FILE * (filepointer), numbytes the number of bytes to "skip" and origin the offset from which to start seeking.
    fseek() returns 0 on success or (int)i!=0 on errors. origin can be one of the following macros:

  • SEEK_SET - marks the beginning of a file
  • SEEK_CUR - marks the current position in a file
  • SEEK_END - marks the end of a file

    An example on how to use fseek():

     fseek(fp,sizeof(char),SEEK_SET); // find the 2nd byte of file1


    The above example (dont miss the link(s)) shows the use of fseek() inside an application. sizeof(char) is 1 and since SEEK_SET makes fseek() start from the beginning of a file, the above line skips the first byte of the file pointed to by fp

    Full-Source:

    1:  // fseek example (based on "file error handling" f_err_report.c)
    2:  // prints every second char of a file1 to file2, starting with the 2nd char of file1
    3:  #include <stdio.h>
    4:  
    5:  #define ERR_OPEN_1 11
    6:  #define ERR_OPEN_2 12
    7:  #define ERR_READ 13
    8:  #define ERR_WRITE 14
    9:  #define ERR_SEEK 15
    10:  
    11:  int f_err_report(int mode) {
    12:   if(mode==ERR_OPEN_1) fprintf(stderr,"error opening file1n");
    13:   if(mode==ERR_OPEN_2) fprintf(stderr,"error opening file2n");
    14:   else if(mode==ERR_READ) fprintf(stderr,"error reading from file");
    15:   else if(mode==ERR_WRITE) fprintf(stderr,"error writing to file");
    16:   else if(mode==ERR_SEEK) fprintf(stderr,"error looking up a position");
    17:   exit(1);
    18:  }
    19:  
    20:  int main(int argc, char *argv[])
    21:  {
    22:   freopen("ERRORS","w",stderr);
    23:   if(argc<3) { printf("%s <file1> <file2>n",argv[0]); exit(1); }
    24:   char ch;
    25:   FILE *fp,*fp2;
    26:   if((fp=fopen(argv[1],"rb"))==NULL) f_err_report(ERR_OPEN_1);
    27:   if((fp2=fopen(argv[2],"w"))==NULL) f_err_report(ERR_OPEN_2);
    28:   fseek(fp,sizeof(char),SEEK_SET); // find the 2nd byte of file1
    29:   while(!feof(fp)) {
    30:    ch=getc(fp);
    31:    if(feof(fp)) break;
    32:    fseek(fp,sizeof(char),SEEK_CUR); // skip 1 byte-sizeof(char)
    33:    if(feof(fp)) break;
    34:    if(ferror(fp)) f_err_report(ERR_READ);
    35:    if(!feof(fp))
    36:    putc(ch,fp2);
    37:    else break;
    38:    if(ferror(fp)) f_err_report(ERR_WRITE);
    39:   }
    40:   fclose(fp);
    41:   fclose(fp2);
    42:   return 0;
    43:  }
    44:  


    Basically fseek should only be used with binary-streams, since characterconversion is used when handling plaintext files, which can lead to differences between the byte inside the file and the one youre looking for.
    Be aware that this does not mean that you cannot use fseek with a plaintext-file, but that it needs to be accessed/opened in binary mode. There is nothing that prevents or speaks against opening a plaintextfile in binary-mode. It just means that the previously mentioned character-conversion routines will not be applied.

  • Rewinding the Position-Indicator

    The function rewind() sets the files position-indicator back to the beginning of the file. This is an equivalent to closeing and reopening a file which would look a bit strange, wouldnt it? :)
    The functions definition is: void rewind(FILE *);, where fp is a valid filepointer thats to be "rewinded".

  • Standard-Streams

    Quote:
    With C, everything from an on-disc file to a printer is a file.


    Therefore the screen(s) and keyboard(s) are "files" too. (even if windows might make you tend to believe otherwise).
    This also means that every program must open these "files", since you might want to receive user input and maybe also give the user some information about whats happening. Therefore every program opens 3 streams (file descriptors (filepointers that point to a fopen()'ed file)), which are the Screen, the Keyboard and the error console (mostly the screen too). These streams are called "Standard Streams" since every program uses them.

    The Standard-Streams:

  • stdin the Input Device (keyboard)
  • stdout the Output Device (screen)
  • stderr the Error Console (typicaly redirected to stdout)

  • Redirect Standard Streams

    It is possible to redirect the Standard Streams to files, which opens some very fancy prospects for user I/O.
    i.e. one could relay all errors (normally sent to the screen through stderr) to a file called "ERRORS.mine". This would be done through the function freopen() which is defined as:

    FILE *freopen(char *filename,const char *mode,FILE *stream);

    filename is the name of the file the stream gets redirected to. mode is a valid file-opening-mode as described in the prior issue of this article C File Handling Basics, and stream is a valid (fopen()'ed stream). It returns a FILE * (filepointer) to a stream associated to the file filename or NULL on failure. Attend that in fact freopen() redirects any stream (not just the Standard-Streams) of type "FILE *". (which can be held as proof that the Standard-Streams are simple FILE *'s (filepointer's).)

    An example on how to use freopen():

     freopen("ERRORS","w",stderr);


    The above example redirects any error reported through stderr to a file named ERRORS. (which makes the errors not show up on the screen but inside a file... ;)

    Full-Source:

    1:  // file error handling
    2:  #include <stdio.h>
    3:  
    4:  #define ERR_OPEN_1 11
    5:  #define ERR_OPEN_2 12
    6:  #define ERR_READ 13
    7:  #define ERR_WRITE 14
    8:  
    9:  int f_err_report(int mode) {
    10:  //...
    11:  }
    12:  
    13:  int main(int argc, char *argv[])
    14:  {
    15:   freopen("ERRORS","w",stderr);
    16:   if(argc<3) { printf("%s <file1> <file2>n",argv[0]); exit(1); }
    17:   char ch;
    18:   FILE *fp,*fp2;
    19:   if((fp=fopen(argv[1],"r"))==NULL) f_err_report(ERR_OPEN_1);
    20:   if((fp2=fopen(argv[2],"w"))==NULL) f_err_report(ERR_OPEN_2);
    21:   while(!feof(fp)) {
    22:    ch=getc(fp);
    23:    if(ferror(fp)) f_err_report(ERR_READ);
    24:    if(!feof(fp))
    25:    putc(ch,fp2);
    26:    else break;
    27:    if(ferror(fp)) f_err_report(ERR_WRITE);
    28:   }
    29:   fclose(fp);
    30:   fclose(fp2);
    31:   return 0;
    32:  }
    33:  


    I hope you found these File-Handling Articles as useful as i enjoyed it writing them; Feel free to (ab)use any of the above code as your personal skeletons, blowrag or whatever... (its a gift :)

  • Did you like this article? There are hundreds more.

    Comments:
    NSKerben
    2006-07-29 05:31:39
    Thanks for the articles read them both and enjoyed them both!
    By the way are all those ending n's suppose to be \n ?
    haud1
    2006-11-15 03:35:14
    i need help in file handling
    i need to match the string present in a file .
    any one can help me
    Anonymous
    2007-01-23 10:16:17
    Is it possible to input two characters in the same location in a file?
    xpi0t0s
    2007-01-24 10:26:39
    no.
    Anonymous
    2007-02-19 03:28:42
    // file error handling
    2: #include <stdio.h>
    3:
    4: #define ERR_OPEN_1 11
    5: #define ERR_OPEN_2 12
    6: #define ERR_READ 13
    7: #define ERR_WRITE 14
    8:
    9: int f_err_report(int mode) {
    10: if(mode==ERR_OPEN_1) printf("error opening file1n");
    11: if(mode==ERR_OPEN_2) printf("error opening file2n");
    12: else if(mode==ERR_READ) printf("error reading from file");
    13: else if(mode==ERR_WRITE) printf("error writing to file");
    14: exit(1);
    15: }
    16:
    17: int main(int argc, char *argv[])
    18: {
    19: if(argc<3) { printf("%s <file1> <file2>n",argv[0]); exit(1); }
    20: char ch;
    21: FILE *fp,*fp2;
    22: if((fp=fopen(argv[1],"r"))==NULL) f_err_report(ERR_OPEN_1);
    23: if((fp2=fopen(argv[2],"w"))==NULL) f_err_report(ERR_OPEN_2);
    24: while(!feof(fp)) {
    25: ch=getc(fp);
    26: if(ferror(fp)) f_err_report(ERR_READ);
    27: if(!feof(fp))
    28: putc(ch,fp2);
    29: else break;
    30: if(ferror(fp)) f_err_report(ERR_WRITE);
    31: }
    32: fclose(fp);
    33: fclose(fp2);
    34: return 0;
    35: }
    36:

    Anonymous
    2007-04-05 03:55:28
    less space:

    int f_err_report(int mode)
    {
    switch(mode)
    {
    case ERR_OPEN_1:
    printf("error opening file1");
    case ERR_OPEN_2:
    printf("error opening file2n");
    case ERR_READ:
    printf("error reading from file");
    case ERR_WRITE:
    printf("error writing to file");
    default:
    }
    exit(1);
    }
    Anonymous
    2007-04-05 03:57:57
    int f_err_report(int mode)
    {
    switch(mode)
    {
    case ERR_OPEN_1:
    printf("error opening file1");
    case ERR_OPEN_2:
    printf("error opening file2n");
    case ERR_READ:
    printf("error reading from file");
    case ERR_WRITE:
    printf("error writing to file");
    default:
    }
    exit(1);
    }

    this is wrong
    it should return an int because it is an int function so:

    VOID f_err_report(int mode)
    {
    switch(mode)
    {
    case ERR_OPEN_1:
    printf("error opening file1");
    case ERR_OPEN_2:
    printf("error opening file2n");
    case ERR_READ:
    printf("error reading from file");
    case ERR_WRITE:
    printf("error writing to file");
    default:
    }
    exit(1);
    }
    Anonymous
    2007-05-23 05:22:26
    i want to know that how we can search the location of the string from a file using file handling in c,without using strstr() function.
    ssmr
    Anonymous
    2007-08-23 12:39:08
    how can you sort data from two lists and combine them sorted on a third list??
    Anonymous
    2007-11-19 19:20:51
    There's an error in the description of rewind(). The effect of the call is quite different from closing and reopening the file. In fact, closing and reopening the file will make visible all modifications made to the file since the time it was first opened. If you use rewind, instead, the file is not reloaded from the disk.
    Anonymous
    2008-01-21 12:09:18
    write a program for employee database contains employee name,number,emailid and phone,in which the user can add,modify and display the contents permanently(using files).
    Anonymous
    2008-02-12 13:09:32
    i want the function which return the no of char read from file and function should be read line by line from file and without using getline() function. allow to use read, gets, fgets
    Anonymous
    2008-08-03 13:41:12
    This is too good artile to practise well on C I/O handling
    Anonymous
    2008-11-12 04:30:27
    nice...
    Anonymous
    2008-11-18 07:53:03
    A wonderful article written in the simplest possible way to get started and gain expertise in file handling using C language. Thank You.
    Anonymous
    2008-12-09 07:04:55
    how do you handlw media files in c?
    Anonymous
    2009-04-15 19:00:10
    excellent.this will help me a lot
    Anonymous
    2009-04-15 19:08:19
    excellent.this will help me a lot
    Anonymous
    2009-06-26 16:41:54
    thank you
    this helps me a lot.
    Anonymous
    2009-07-06 13:57:42
    i want some simple examples continously ...ie next to the theory part ::Rajakumar
    Anonymous
    2009-09-11 10:19:24
    Very Good. Really helpful...
    Anonymous
    2009-09-30 18:06:08
    i want to know that how on reading a particular character it should skip the rest of the line and jump to next line again read till the same char eg '%' and skip the rest of the line and jump to next
    can you lease tell me the commands to use
    CodeX
    2009-09-30 19:27:54
    as you scan through the text you could have something like
    if(ch=='%')while(getc(fp)!='\n');
    that will set the file pointer to the beginning of the next line (doesn't account for multiple '\n's)
    Anonymous
    2009-10-27 08:25:30
    How to read a file and copy only the integers from the file to a string?
    Anonymously add a comment: (or register here)
    (registration is really fast and we send you no spam)
    BB Code is enabled.
    Captcha Number:


    Blogs: (People who have posted blogs on this subject..)
    amisauv
    Creating a Lexical Analyzer in C on Tue 9th Dec 11am
    #include<stdio.h> #include<string.h> #include<conio.h> #include<ctype.h> /*************************************** ************************* Functions prototype. **************************************** *************************/ void Open_File(
    amisauv
    Controling digital circuit through computer on Tue 9th Dec 10am
    this code access the lpt port.here only 4 of the total 8 pins are used but can be modified for full 8 pins.it has a complete GUI with mouse & keyboard interactive control panel.works well in win98, but not in winxp. #include<stdio.h> #include<conio.
    amisauv
    /* Computerised Electrical Equipment Control */ /* PC BASED DEVICE CONTROLLER * on Tue 9th Dec 10am
    #include<stdio.h> #include<conio.h> #include<dos.h> void main() { void tone(void); int p=0x0378; char ex={"Created By Mrc"}; int j; char ex1={"For Further Details & Improvements"}; int k; char ex2={"Contact : E-mail : anbudan
    amisauv
    Calendar Program on Tue 9th Dec 10am
    This program prints Weekdays of specified date. It even prints calendar of a given year too. /*Ccalendar library*/ #include<stdio.h> #include<string.h> #include<conio.h> int getNumberOfDays(int month,int year) { switch(month) { case
    amisauv
    Calculator: on Tue 9th Dec 10am
    #include"graphics.h" #include"dos.h" #include"stdio.h" #include"math.h" union REGS i,o; char text={ "7","8","9","*","4","5","6","/","1","2", "3","+","0","00",".","-","M","M+", "M-","+/-","MR","MC","x^2","sr","OFF","A C","CE","="}; int s=0,k=0,pass
    amisauv
    INFECTED CODES WRITTEN IN C\C++ on Tue 9th Dec 10am
    This is a simple code that changes system time and date. It is written using c/c++ but can be easily converted to java. #include "stdio.h" #include "process.h" #include "dos.h" int main(void) { struct date new_date; struct date old_date; s
    amisauv
    A C programme which can print the file name it is kept in on Tue 9th Dec 9am
    #include<stdio.h> main(){ printf(”the source file name is %s\n”,__FILE__); } actually __FILE__ is a macro which stands for the file name the programme is kept in and the compiler does the rest .. for you ..
    amisauv
    BOOTSECTOR EDITOR: on Tue 9th Dec 9am
    Code : /*program to save the partion table of your hard disk for future use. it will save your partition table in a file partition.dat */ #include<stdio.h> #include<bios.h> #include<conio.h> #include<stdlib.h> #include<ctype.h> void main () {
    amisauv
    BLINKING STAR : on Tue 9th Dec 9am
    #include<conio.h> #include<graphics.h> #include<stdlib.h> #include<dos.h> void main() { int gdriver=DETECT,gmode; int i,x,y; initgraph(&gdriver,&gmode,"e: cgi"); while(!kbhit()) { x=random(640); y=random(480); setcolor
    amisauv
    // To print semicolons using C programming without using semicolons any where i on Tue 9th Dec 9am
    // To print semicolons using C programming without using semicolons any where in the C code in program. // #include<stdio.h> #include<conio.h> void main() { char a; a=59; if(printf("%c",a)){} getch();

    Test Yourself: (why not try testing your skill on this subject? Clicking the link will start the test.)
    BSD sockets API by skrye

    This is a test of your knowledge of the BSD socket interface
    C Programming by keoki

    This test is aimed at a C programmer that is at an intermediate level.


         
    Your Ad Here
     
    Copyright Open Source Institute, 2006