Reading From a File

Embed Size (px)

Citation preview

  • 8/7/2019 Reading From a File

    1/19

    fscanf()

    fscanf() is afieldoriented function and is inappropriate for use in a robust, general-purpose textfile reader. It has two major drawbacks:

    y You must know the exact data layout of the input file in advance and rewrite the functioncall for every different layout.

    y It's difficult to read text strings that contain spaces because fscanf() sees space characters

    as field delimiters.

    For these reasons, I chose notto include fscanf() in this presentation. Theprogram included heredoes, however, have the ability to read text files using fscanf(). If you download and compile it,

    you can demonstrate the limitations for yourself.

    < Back toFile Open Modes | ^ Up to Top | Forward to The InputFiles >

    fgets()

    fgets() is a line oriented function. The ANSI prototype is:

    char *fgets(char *s,int n,FILE *stream);

    The function reads from the stream pointed to by stream and places the output into the character

    array pointed to by s. It will stop reading when any of the following conditions are true:

    y It has read n - 1 bytes (one character is reserved for the null-terminator), or

    y It encounters a newline character (a line-feed in the compilers tested here), or

    y It reaches the end of file, or

    y A read error occurs.

    fgets() automatically appends a null-terminator to the data read.

    On the surface, fgets() seems like the ideal function to read a text file line-by-line, but as theprogram output shows, it is not without limitations.

    < Back toFile Open Modes | ^ Up to Top | Forward to The InputFiles >

    fgetc()

  • 8/7/2019 Reading From a File

    2/19

    fgetc() is a characteroriented function. The ANSI prototype is:

    int fgetc(FILE *stream);

    The function returns the nextcharacter in the stream pointed to by stream as an unsigned char

    converted to an int. It will stop reading at the end of file or if a read error occurs.

    fgetc() gives you more control than fgets(), but reading a file byte-by-byte from disk is ratherinefficient.

    < Back toFile Open Modes | ^ Up to Top | Forward to The InputFiles >

    fread()

    fread() is a blockoriented function. The ANSI prototype is:size_t fread(void *ptr,

    size_t size,size_t nmemb,FILE *stream);

    The function reads from the stream pointed to by stream and places the output into the arraypointed to by ptr. It will stop reading when any of the following conditions are true:

    y It has read nmemb elements of size size, or

    y It reaches the end of file, or

    y A read error occurs.

    fread() gives you as much control as fgetc(), and has the advantage of being able to read morethan one character in a single I/O operation. In fact, memory permitting, you can read the entire

    file into an array and do all of your processing in memory. This has significant performanceadvantages.

    fread() is often used to read fixed-length data records directly into structs, but you can use it to

    read any file. It's my personal choice for reading most disk files.

    Theprogram included here demonstrates how to read an entire file into an array using fread(). It

    also contains an example ofdynamic memory allocation to resize an array so that it canaccommodate the whole file without knowing the file's size in advance.

  • 8/7/2019 Reading From a File

    3/19

    /**************************************************************************/

    Opening A File

    Before we can write information to a file on a disk or read it, we must open the file. Opening a fileestablishes a link between the program and the operating system, about, which file we are going toaccess and how. We provide the operating system with the name of the file and whether we plan to reador write to it. The link between our program and the operating system is a structure called FILE whichhas been defined in the header file stdio.h . Therefore, it is necessary to always include this file whenwe are doing high level disk I/O. When we request the operating system to a file, what we get back is apointer to the structure FILE. That is why, we make the following declaration before opening the file,

    FILE*fp ;

    Each file we open will have its own FILE structure. The FILE structure contains information about the filebeing used, such as its current size, its location in memory etc. More importantly it contains a character

    pointer which points to the character that is about to get read.

    Now let us understand the following statements,

    FILE *fp ;fp = fopen ( PR1.C, r ) ;

    fp is a pointer variable, which contains address of the structure FILE which has been in the header filestdio.h.

    fopen( ) will open a file PR1.C in read mode, which tells the compiler that we would be reading thecontents of the file. Note that r is a string and not a character; hence the double quotes and not singlequotes.

    In fact, fopen( ) performs three important tasks when you open the file in r mode:

    (a) Firstly it searches on the disk the file to be opened.(b) If the file is present, it loads the file from the disk into memory. Of course if the file is very big, then itloads the file part by part.If the file is absent, fopen( ) returns a NULL.NULL is a macro defined instdio.h which indicates that you failed to open the file.(c) It sets up a character pointer which points to the first character of the chunk of memory where thefile has been loaded.

    Reading from A file

    Once the file has been opened for reading using fopen( ), the files contents are brought into memoryand a pointer points to the very first character. To read the files contents from memory there exists afunction called fgetc( ). This has been used in our sample program through,

  • 8/7/2019 Reading From a File

    4/19

    ch = fgetc ( fp ) ;

    fgetc( ) reads the character from current pointer position, advances the pointer position so that it nowpoints to the next character, and returns the character that is read, which we collected in the variable ch.Note that once the file has been opened, we refer to the file through the file pointer fp.

    We have to use the function fgetc( ) within an indefinite while loop. There has to be a way to break outof this while,it is the moment we reach the end of file. End of file is signified by a special character in thefile, when it is created. This character can also be generated from the keyboard by typing ctrl Z.

    While reading from the file, when fgetc( ) encounters this special character, instead of returning thecharacter that it has read, it returns the macro EOF. The EOF macro has been defined I the file stdio.h.In place of the function fgetc( ) we could have as well used the macro getc( ) with the same effect.

    Opening A File

    There is a possibility that when we try to open a file using the function fopen( ), the file may not beopened. While opening the file in r mode, this may happen because the file being opened may not bepresent on the disk at all. And you obviously cannot read a file which doesnt exist. Similarly, whileopening the file for writing, fopen( ) may fail due to a number of reasons, like, disk space may beinsufficient to open a new file, or the disk may be write protected and so on.

    So it is important for any program that accesses disk files to check whether a file has been openedsuccessfully before trying to read or write to the file. If the file opening fails due to any of the severalreasons mentioned above, the fopen( ) function returns a value NULL (defined in stdio.h as #defineNULL 0).

    Here is how this can be handled in a program

    Code: C

    #include stdio.hmain(){

    FILE*fp ;

    Fp = fopen ( PR1.C,r ) ;if( fp == NULL){

    puts ( cannot open file ) ;exit() ;

    }}

    File Opening Modes

    We open the file in read ( r ) mode. However, r is but one of the several modes in which we can open

  • 8/7/2019 Reading From a File

    5/19

    a file. Following is a list of all possible modes in which a file can be opened . the tasks performed byfopen( ) when a file is opened in each of these modes are also mentioned.

    r :- Searches file. If the file exists, loads it into memory and sets up a pointer which points to the firstcharacter in it. If the file doesnt exit it returns NULL.

    Operations possible reading from the file.

    w :- Searches file. If the file exists, its contents are overwritten. If the file doesnt exit, a new file iscreated. Returns NULL, if unable to open file.

    Operations possible writing to the file.

    a :- Searches file. If the file exists, loads it into memory and sets up a pointer which points to the firstcharacter in it. If the file doesnt exist, a new file is created. Returns NULL, if unable to open file.

    Operations possible appending new contents at the end of file.

    r+ :- Searches file. If it exists, loads it into memory and sets up a pointer which points to the first

    character in it. If file doesnt exist it returns NULL.

    Operations possible reading existing contents, writing new contents, modifying existing contents of thefile.

    w+ :- Searches file. If the file exists, its contents are destroyed. If the file doesnt exist a new file iscreated. Returns NULL, if unable to open file.

    Operations possible writing new contents, reading them back and modifying existing contents of thefile.

    a+ :-Searches file. If the file exists, loads it in to memory and sets up a pointer which points to the firstcharacter in it. If the file doesnt exist, a new file is created. Returns NULL, if unable to open file.

    Operations possible reading existing contents, appending new contents to end of file. Cannot modifyexisting contents.

    Writing to A File

    The fputc( ) function is similar to the putch( ) function, in the sense that both output characters.

    However, putch( ) function always writes to the VDU, whereas, fputc( ) writes to the file. Which file? Thefile signified by ft. the writing process continues till all characters from the source file have been writtento the target file, following which the while loop terminates.

    We have already seenthe function fgetc( ) which reads characters from a file. Its

    Counterpart is a function called fputc( ) which writes characters to a file. As a practical use of thesecharacter I/O functions we can copy the contents of one file into another, as demonstrated in thefollowing example. This program takes the contents of a text file and copies them into another text file,

  • 8/7/2019 Reading From a File

    6/19

    character by character.

    Example

    Code: C

    #include stdio.h

    main(){

    FILE *fs, *ft ;char ch ;

    fs = fopen ( pr1.c, r ) ;if( fs == NULL){

    puts ( Cannot open source file ) ;exit() ;

    }

    ft = fopen ( pr2.c, w ) ;

    if( ft ==NULL

    ){puts ( Cannot open target file ) ;fclose ( fs ) ;exit() ;

    }

    while(1){

    ch = fgetc ( fs ) ;

    if( ch == EOF )break ;

    else

    fputc ( ch, ft ) ;}

    fclose ( fs ) ;fclose (t

    }

    Closing The File

    When we have finished reading from the file, we need to close it. This is done using the function fclose( )

    through the statement,

    fclose ( fp ) ;

    this deactivates the file and hence it can no longer be accessed using getc( ). Once again we dont use

    the filename but the file pointer fp.

  • 8/7/2019 Reading From a File

    7/19

    /********************************************************************************/

    This section demonstrates you to read a line from the file. You can see in the given example, weprompt the user to enter the name of the file to read. The library functiongets() get the entered filefrom the console. The type FILE stores the information related to file stream. The file pointer*fcallsthe function fopen() which will open the entered file. If no error occurred while opening the file thenfgets(st, 60, p) reads the data from the file. In case if error occurred, it will displays the errormessage.

    strlen(st)- This function determines the length of the string .

    Here is the code:

    FILEREAD.C

    #include #include #include voidmain(charst[80]) {

    FILE *p;

    charfile[80];printf("Open File: ", &file);gets(file);p = fopen(file, "r");if (p) {fgets(st, 60, p);st[strlen(st)] = 0;printf("The data of the file is: %s\n", st);getch();

    } else{printf("File does not exist.\n");

    }fclose(p);

    }

    Output will be displayed as:

    #include

    #include

    #include

    void main(char st[80]){

    FILE *p;

    char file[80];

    printf("Open File: ", &file);

    gets(file);

    p = fopen(file, "r");

  • 8/7/2019 Reading From a File

    8/19

    if (p) {

    fgets(st, 60, p);

    st[strlen(st)] = 0;

    printf("The data of the file is: %s\n", st);

    getch();}

    else{

    printf("File does not exist.\n");

    }

    fclose(p);

    }

    /*********************************************************************/

    Open a file and read its content using fgetc

    #include

    #include

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

    {

    FILE *fp;

    charch;

    if((fp = fopen(argv[ 1 ],"r"))==NULL) {

    printf("Cannot open file.\n");

    exit(1);

    }

    while((ch = fgetc( fp )) != EOF) {

  • 8/7/2019 Reading From a File

    9/19

    printf("%c", ch);

    }

    fclose(fp);

    return 0;

    }

    /**********************************************************************/

    C - Reading from a Text File

    /*** File FILE_3.C**** Illustrates how to read from a file.**

    ** The file is opened for reading. Each line is successively fetched** using fgets command. The string is then converted to a long integer.**** Note that fgets returns NULL when there are no more lines in the file.**** In this example file ELAPSED.DTA consists of various elapsed times in** seconds. This may have been the result of logging the time of events** using an elapsed time counter which increments each second from the** time the data logger was placed in service.**** Typical data in elapsed.dta might be;**** 65** 142** 1045** 60493** 124567****** Peter H. Anderson, 4 April, '97*/

    #include /* required for file operations */

  • 8/7/2019 Reading From a File

    10/19

    #include /* for clrscr */#include /* for delay */

    FILE *fr; /* declare the file pointer */

    main()

    {int n;long elapsed_seconds;char line[80];clrscr();

    fr = fopen ("elapsed.dta", "rt"); /* open the file for reading *//* elapsed.dta is the name of the file *//* "rt" means open the file for reading text */

    while(fgets(line, 80, fr) != NULL){

    /* get a line, up to 80 chars from fr. done if NULL */

    sscanf (line, "%ld", &elapsed_seconds);/* convert the string to a long int */printf ("%ld\n", elapsed_seconds);

    }fclose(fr); /* close the file prior to exiting the routine */

    } /*of main*/

    Related examples in the same category

    1. Reading strings from a file in reverse order

    2. Messing about with formatted file I/O

    3. Viewing the contents of a file

    4. Search a set of numbers

    5. Count the number of characters in a f ile

    6. Get string from file

  • 8/7/2019 Reading From a File

    11/19

    7. fscanf() - fprintf() example

    8. Get the next int value from a stream: how to use getw and putw

    9. Get the next character from a stream: how to use fgetc

    10.Get a string from a stream: how to use fgets

    11.Read formatted data from a stream: how to use fscanf

    12.Get the next character: how to use getc

    13.Create a file, write content and read the content

    14.Reset the file reader pointer

    15.Check for errors: How to use ferror

    Get the next character: how to use getc

    #include

    int main ()

    {

    FILE *file;

    charc;

    int n = 0;

    file = fopen("my.txt", "r");

    if (file==NULL)

    perror ("Error reading file");

    else

    {

    do {

    c = getc (file);

    if (c == '$')

    n++;

  • 8/7/2019 Reading From a File

    12/19

    }while(c != EOF);

    fclose (file);

    printf ("my.txt contains %d $.\n",n);

    }

    return 0;

    }

    Get a string from a stream: how to use fgets

    #include

    int main(){

    FILE *file;charstring [100];

    file = fopen ("my.txt" , "r");if (file == NULL)

    perror ("Error reading file");else{fgets (string , 100 , file);puts (string);fclose (file);

    }return 0;

    }

  • 8/7/2019 Reading From a File

    13/19

    /******************************************************************************/

    sscanffunction

    int sscanf ( const char * str, const char * format, ...);

    Read formatted data from string

    Reads data from strand stores them according to the parameter formatinto the locations given by

    the additional arguments. Locations pointed by each additional argument are filled with theircorresponding type of value specified in the formatstring.

    Parametersstr

    C string that the function processes as its source to retrieve the data.

    format

    C string that contains one or more of the following items:

    y

    Wh

    ite

    space

    ch

    aracte

    r: the function will read and ignore any whitespace characters(this includes blank spaces and the newline and tab characters) which are encounteredbefore the next non-whitespace character. This includes any quantity of whitespacecharacters, or none.

    y Non-whitespace character, except percentage signs (%): Any character that isnot either a whitespace character (blank, newline or tab) or part of a format specifier(which begin with a % character) causes the function to read the next character fromstr, compare it to this non-whitespace character and if it matches, it is discarded andthe function continues with the next character offormatand str. If the character doesnot match, the function fails and returns.

  • 8/7/2019 Reading From a File

    14/19

    y Format specifiers: A sequence formed by an initial percentage sign (%) indicates aformat specifier, which is used to specify the type and format of the data to beretrieved from the strstring and stored in the locations pointed by the additionalarguments. A format specifier follows this prototype:

    [=%[*][width][modifiers]type=]

    where:

    *An optional starting asterisk indicates that the data is to be retrieved from

    the strstring but ignored, i.e. it is not stored in the corresponding argument.

    widthSpecifies the maximum number of characters to be read in the current

    reading operation

    modifiers

    Specifies a size different from int (in the case ofd, i and n), unsigned

    int (in the case ofo, u and x) or float (in the case ofe, f and g) for the

    data pointed by the corresponding additional argument:

    h :short int (for d, i and n), or unsigned short int (for o, u and x)

    l :long int (for d, i and n), or unsigned long int (for o, u and x), or

    double (for e, f and g)

    L :long double (for e, f and g)

    typeA character specifying the type of data to be read and how it is expected to

    be read. See next table.

    ysscanf type specifiers:

    type Qualifying InputType of

    argument

    c

    Single character: Reads the next character. If a width

    different from 1 is specified, the function reads width characters

    and stores them in the successive locations of the array passed

    as argument. No null character is appended at the end.

    char *

    dDecimal integer: Number optionally preceeded with a + or -

    sign.int *

    e,E,f,g,G

    Floating point: Decimal number containing a decimal point,

    optionally preceeded by a + or - sign and optionally folowed by

    the e or E character and a decimal number. Two examples of

    valid entries are -732.103 and 7.12e4

    float *

    o Octal integer. int *

    s String of characters. This will read subsequent characters

    until a whitespace is found (whitespace characters are

    char *

  • 8/7/2019 Reading From a File

    15/19

    considered to be blank, newline and tab).

    u Unsigned decimal integer.unsigned

    int *

    x,X Hexadecimal integer. int *

    additional arguments

    The function expects a sequence of references as additional arguments, each one pointing to

    an object of the type specified by their corresponding %-tag within the formatstring, in the

    same order.

    For each format specifier in the formatstring that retrieves data, an additional argument

    should be specified.

    These arguments are expected to be references (pointers): if you want to store the result of a

    sscanf operation on a regular variable you should precede its identifier with the reference

    operator, i.e. an ampersand sign (&), like in:

    int n;

    sscanf (str,"%d",&n);

    Return ValueOn success, the function returns the number of items succesfully read. This count can match the

    expected number of readings or fewer, even zero, if a matching failure happens.

    In the case of an input failure before any data could be successfully read, EOF is returned.

    Example1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    /* sscanf example */#include

    int main (){char sentence []="Rudolph is 12 years old";char str [20];int i;

    sscanf (sentence,"%s %*s %d",str,&i);printf ("%s -> %d\n",str,i);

    return 0;}

    Output:

    Rudolph -> 12

  • 8/7/2019 Reading From a File

    16/19

    See also

    scanf Read formatted data from stdin (function)

    sprintf Write formatted data to string (function)

    /********************************************************************************/

    There is also a function sscanf that reads from a string instead of the standard input:

    int sscanf(char *string, char *format, arg1, arg2, ...)

    It scans the string according to the format informat and stores the resulting values througharg1,

    arg2, etc. These arguments must be pointers.

    The format string usually contains conversion specifications, which are used to control conversion of

    input. The format string may contain:

    y Blanks or tabs, which are not ignored.

    y Ordinary characters (not %), which are expected to match the next non-white space character

    of the input stream.

    y Conversion specifications, consisting of the character%, an optional assignment suppression

    character*, an optional number specifying a maximum field width, an optionalh, l orL

    indicating the width of the target, and a conversion character.

    A conversion specification directs the conversion of the next input field. Normally the result is places in

    the variable pointed to by the corresponding argument. If assignment suppression is indicated by the *

    character, however, the input field is skipped; no assignment is made. An input field is defined as a string

    of non-white space characters; it extends either to the next white space character or until the field width,

    is specified, is exhausted. This implies thatscanf will read across boundaries to find its input, since

    newlines are white space. (White space characters are blank, tab, newline, carriage return, vertical tab,

    and form-feed.)

    The conversion character indicates the interpretation of the input field. The corresponding argument

    must be a pointer, as required by the call-by-value semantics of C. Conversion characters are shown

    in Table 7.2.

    Basic Scanf Conversions

    Character Input Data; Argument type

  • 8/7/2019 Reading From a File

    17/19

    d decimal integer; int *

    i integer; int *. The integer may be in octal (leading 0) or hexadecimal (leading 0x or 0X).

    o octal integer (with or without leading zero); int *

    u unsigned decimal integer; unsigned int *

    x hexadecimal integer (with or without leading 0x or 0X); int *

    ccharacters; char *. The next input characters (default 1) are placed at the indicated spot. The

    normal skip-over white space is suppressed; to read the next non-white space character, use %1s

    scharacter string (not quoted); char *, pointing to an array of characters long enough for the string

    and a terminating '\0' that will be added.

    e,f,g floating-point number with optional sign, optional decimal point and optional exponent; float *

    % literal %; no assignment is made.

    The conversion charactersd, i, o, u, and x may be preceded byh to indicate that a pointer to

    short rather than int appears in the argument list, or byl (letter ell) to indicate that a pointer to

    long appears in the argument list.

    As a first example, the rudimentary calculator can be written withscanf to do the input conversion:

    #include

    main() /* rudimentary calculator */

    {

    double sum, v;

    sum = 0;

    while (scanf("%lf", &v) == 1)

    printf("\t%.2f\n", sum += v);

    return 0;

    }

    Suppose we want to read input lines that contain dates of the form

    25 Dec 1988

    The scanf statement is

    int day, year;

    char monthname[20];

  • 8/7/2019 Reading From a File

    18/19

    scanf("%d %s %d", &day, monthname, &year);

    No & is used with monthname, since an array name is a pointer.

    Literal characters can appear in thescanf format string; they must match the same characters in

    the input. So we could read dates of the formmm/dd/yy with the scanf statement:

    int day, month, year;

    scanf("%d/%d/%d", &month, &day, &year);

    scanf ignores blanks and tabs in its format string. Furthermore, it skips over white space (blanks, tabs,

    newlines, etc.) as it looks for input values. To read input whose format is not fixed, it is often best to read

    a line at a time, then pick it apart withscanf. For example, suppose we want to read lines that might

    contain a date in either of the forms above. Then we could write

    while (getline(line, sizeof(line)) > 0) {

    if (sscanf(line, "%d %s %d", &day, monthname, &year) == 3)

    printf("valid: %s\n", line); /* 25 Dec 1988 form */

    else if (sscanf(line, "%d/%d/%d", &month, &day, &year) == 3)

    printf("valid: %s\n", line); /* mm/dd/yy form */

    else

    printf("invalid: %s\n", line); /* invalid form */

    }

    Calls to scanf can be mixed with calls to other input functions. The next call to any input function will

    begin by reading the first character not read byscanf.

    A final warning: the arguments toscanf and sscanfmustbe pointers. By far the most common

    error is writing

    scanf("%d", n);

    instead of

    scanf("%d", &n);

    This error is not generally detected at compile time.

    If this tutorial doesn't answer your question, and you have a specific question, just ask an

    expert here. Post your question to get a direct answer.

  • 8/7/2019 Reading From a File

    19/19