You are on page 1of 11

Enumerations (enum)

Enumerations create new data types to contain something different that is not limited to the
values fundamental data types may take. Its form is the following:

enum enumeration_name
{
value1,
value2,
value3,
.
.
} object_names;

For example, we could create a new type of variable called colors_t to store colors with the
following declaration:

enum colors_t {black, blue, green, cyan, red, purple, yellow, white};

Notice that we do not include any fundamental data type in the declaration. To say it somehow,
we have created a whole new data type from scratch without basing it on any other existing type.
The possible values that variables of this new type color_t may take are the new constant values
included within braces. For example, once the colors_t enumeration is declared the following
expressions will be valid:

colors_t mycolor;

mycolor = blue;
if (mycolor == green) mycolor = red;

Enumerations are type compatible with numeric variables, so their constants are always assigned
an integer numerical value internally. If it is not specified, the integer value equivalent to the first
possible value is equivalent to 0 and the following ones follow a +1 progression. Thus, in our
data type colors_t that we have defined above, black would be equivalent to 0, blue would be
equivalent to 1, green to 2, and so on.

We can explicitly specify an integer value for any of the constant values that our enumerated
type can take. If the constant value that follows it is not given an integer value, it is automatically
assumed the same value as the previous one plus one. For example:

enum months_t { january=1, february, march, april,


may, june, july, august,
september, october, november, december} y2k;
In this case, variable y2k of enumerated type months_t can contain any of the 12 possible values
that go from january to december and that are equivalent to values between 1 and 12 (not
between 0 and 11, since we have made january equal to 1).

enum month
{ jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec };

enum month this_month;

this_month = feb;

In the above declaration, month is declared as an enumerated data type. It consists of a set of
values, jan to dec. Numerically, jan is given the value 1, feb the value 2, and so on. The variable
this_month is declared to be of the same type as month, then is assigned the value associated
with feb. This_month cannot be assigned any values outside those specified in the initialization
list for the declaration of month.

#include <stdio.h>

main()
{
char *pwest = "west",*pnorth = "north", *peast="east", *psouth = "south";
enum location { east=1, west=2, south=3, north=4};
enum location direction;

direction = east;

if( direction == east )


printf("Cannot go %s\n", peast);
}

The variables defined in the enumerated variable location should be assigned initial values.

Defined data types (typedef)


C allows the definition of our own types based on other existing data types. We can do this using
the keyword typedef, whose format is:

typedef existing_type new_type_name ;

where existing_type is a C fundamental or compound type and new_type_name is the name for
the new type we are defining. For example:

typedef char C;
typedef unsigned int WORD;
typedef char * pChar;
typedef char field [50];
In this case we have defined four data types: C, WORD, pChar and field as char, unsigned int,
char* and char[50] respectively, that we could perfectly use in declarations later as any other
valid type:

C mychar, anotherchar, *ptc1;


WORD myword;
pChar ptc2;
field name;

typedef does not create different types. It only creates synonyms of existing types. That means
that the type of myword can be considered to be either WORD or unsigned int, since both are in
fact the same type.

typedef can be useful to define an alias for a type that is frequently used within a program. It is
also useful to define types when it is possible that we will need to change the type in later
versions of our program, or if a type you want to use has a name that is too long or confusing.

File Handling

Abstractly, a file is a collection of bytes stored on a secondary storage device, which is generally
a disk of some kind. The collection of bytes may be interpreted, for example, as characters,
words, lines, paragraphs and pages from a textual document; fields and records belonging to a
database; or pixels from a graphical image. The meaning attached to a particular file is
determined entirely by the data structures and operations used by a program to process the file. It
is conceivable (and it sometimes happens) that a graphics file will be read and displayed by a
program designed to process textual data.. A file is simply a storage media where programs and
data are stored for machine usage.

Essentially there are two kinds of files that programmers deal with text files and binary files.
These two classes of files will be discussed in the following sections.

ASCII Text files

A text file can be a stream of characters that a computer can process sequentially. It is not only
processed sequentially but only in forward direction. For this reason a text file is usually opened
for only one kind of operation (reading, writing, or appending) at any given time.

Similarly, since text files only process characters, they can only read or write data one character
at a time. (In C Programming Language, Functions are provided that deal with lines of text, but
these still essentially process data one character at a time.) A text stream in C is a special kind of
file. Depending on the requirements of the operating system, newline characters may be
converted to or from carriage-return/linefeed combinations depending on whether data is being
written to, or read from, the file. Other character conversions may also occur to satisfy the
storage requirements of the operating system. These translations occur transparently and they
occur because the programmer has signalled the intention to process a text file.
Binary files

A binary file is no different to a text file. It is a collection of bytes. In C Programming Language


a byte and a character are equivalent. Hence a binary file is also referred to as a character stream,
but there are two essential differences.

1. No special processing of the data occurs and each byte of data is transferred to or from
the disk unprocessed.
2. C Programming Language places no constructs on the file, and it may be read from, or
written to, in any manner chosen by the programmer.

Binary files can be either processed sequentially or, depending on the needs of the application,
they can be processed using random access techniques. In C Programming Language, processing
a file using random access techniques involves moving the current file position to an appropriate
place in the file before reading or writing data. This indicates a second characteristic of binary
files.
They a generally processed using read and write operations simultaneously.

For example, a database file will be created and processed as a binary file. A record update
operation will involve locating the appropriate record, reading the record into memory,
modifying it in some way, and finally writing the record back to disk at its appropriate location
in the file. These kinds of operations are common to many binary files, but are rarely found in
applications that process text files.

File processing consists of creating, storing, and/or retrieving the contents of a file from a
secondary storage medium. For example, it is used to save word processed files to a hard drive,
to store a presentation on floppy disk, or to open a file from a CD-ROM.

What is a buffer?

A buffer is a temporary holding area in memory which acts as an intermediary between a


program and a file or other I/0 device. Information can be transferred between a buffer and a file
using large chunks of data of the size most efficiently handled by devices like disc drives.
Typically, devices like discs transfer information in blocks of 512 bytes or more, while program
often processes information one byte at a time. On output, a program first fills the buffer and
then transfers the entire block of data to a hard disc, thus clearing the buffer for the next batch of
output.

File processing is traditionally performed using the FILE structure. FILE is a structure and it is
defined in the stdio.h header file. This object is equipped with variables used to indicate what
operation would be performed. To use this structure, you can first declare an instance of the
FILE structure. Here is an example:

FILE *ptr;

After instantiating this structure, you can define what to do with it, using one of the provided
functions. Because FILE was created as a C structure, it does not have member functions. The
functions used to perform its related operations on files are also declared in the stdio.h header
file.

Opening and/or Saving Files

To create a new file, open an existing file, or save a file, you use the fopen() function. Its syntax
is:

FILE *fopen(const char *FileName, const char *Mode);

The first argument, FileName, must be a valid name of a file. If the user is creating or saving a
new file, you can let him specify the name of the file, following the rules of the operating
system. If the user is opening an existing file, you can make sure the file really exists, retrieve its
name and pass it to the fopen() function.

Because the fopen() function is used to save a new file, to open an existing one, or to save a file
that was only modified, the second argument, Mode, actually allows you to decide what
operation the function will be used to perform. This argument is a short string of one or two
characters and can be one of the following:

Mode Role If the file already exists If the file does not exist
 it would be opened and
Opens an existing file for can be read. After the file
r the operation would fail
reading only is opened, the user
cannot add data to it
the file's contents would
a new file is created and can be
w Saves a new file be deleted and replaced
written to
by the new content
the file is opened and can
Opens an existing file, be modified or updated.
saves new file, or saves a New information written a new file is created and can be
a
existing file that has been to the file would be written to
modified added to the end of the
file
the file is opened and its
r+ Opens an existing file existing data can be the operation would fail
modified or updated
the file is opened, its
Creates new file or saves contents would be a new file is created and can be
w+
an existing one deleted and replaced with written to
the new contents
it is opened and its
contents can be updated.
Creates a new file or New information written a new file is created and can be
a+
modifies an existing one to the file would be written to
added to the end of the
file
If the operation performed using the fopen() function is successful, the function returns a pointer
to the FILE instance that was declared.

After using a file, you should/must close its stream. This is done using the fclose() function. Its
syntax is:

int fclose(FILE *stream);

To use this function, you must let it know what instance of the FILE object you are closing.

Writing Data to a File

To save a file, you must write data to its contents. This operation is performed using the fprintf()
function. The syntax is :

int fprintf(FILE *stream, const char *format, ...);

The fprintf() function takes a few arguments depending on how it is used. The first parameter,
stream, must be an instance of a FILE structure.

The second parameter, format, is a string that specifies how data will be formatted and possibly
positioned in the stream instance. The string typically starts with the % symbol followed by one
or more characters that represents a format. Different formats are used depending on the type of
data of the variable that is being written. You can use one the following characters:

After specifying the format, you can type the name of the variable that is being saved. You can
repeatedly use the fprintf() function for each variable you want to save.

Reading Data From a File

If you have a file and want to retrieve data stored from it, you can use the fscanf() function. The
syntax is :

int fscanf(FILE *stream, const char *format[, address, ...]);

The first parameter, stream, must be a valid instance of a FILE structure.

The second parameter, format, follows the same rules as for the fprintf() function. After typing
the format, type the name of the variable that is being retrieved.

fopen

Syntax:
#include <stdio.h>
FILE *fp=fopen( const char *fname, const char *mode );

The fopen() function opens a file indicated by fname and returns a stream associated with that
file. If there is an error, fopen() returns NULL. mode is used to determine how the file will be
treated (i.e. for input, output, etc)
Mode Meaning
"r" Open a text file for reading
"w" Create a text file for writing
"a" Append to a text file
"rb" Open a binary file for reading
"wb" Create a binary file for writing
"ab" Append to a binary file
"r+" Open a text file for read/write
"w+" Create a text file for read/write
"a+" Open a text file for read/write
"rb+" Open a binary file for read/write
"wb+" Create a binary file for read/write
"ab+" Open a binary file for read/write

An example:

char ch;
FILE *input = fopen( "stuff", "r" );
ch = getc( input );

fclose

Syntax:
#include <stdio.h>
int fclose( FILE *stream );

The function fclose() closes the given file stream, deallocating any buffers associated with that
stream. fclose() returns 0 upon success, and EOF otherwise.

feof

Syntax:
#include <stdio.h>
int feof( FILE *stream );

The function feof() returns a nonzero value if the end of the given file stream has been reached.

fflush

Syntax:
#include <stdio.h>
int fflush( FILE *stream );

If the given file stream is an output stream, then fflush() causes the output buffer to be written to
the file. If the given stream is of the input type, then fflush() causes the input buffer to be cleared.
fflush() is useful when debugging, if a program segfaults before it has a chance to write output to
the screen. Calling fflush( STDOUT ) directly after debugging output will ensure that your
output is displayed at the correct time.

printf( "Before first call\n" );


fflush( STDOUT );
shady_function();
printf( "Before second call\n" );
fflush( STDOUT );
dangerous_function();

fgetc

Syntax:
#include <stdio.h>
int fgetc( FILE *stream );

The fgetc() function returns the next character from stream, or EOF if the end of file is reached
or if there is an error.

fgetpos

Syntax:
#include <stdio.h>
int fgetpos( FILE *stream, fpos_t *position );

The fgetpos() function stores the file position indicator of the given file stream in the given
position variable. The position variable is of type fpos_t (which is defined in stdio.h) and is an
object that can hold every possible position in a FILE. fgetpos() returns zero upon success, and a
non-zero value upon failure.

fgets

Syntax:
#include <stdio.h>
char *fgets( char *str, int num, FILE *stream );

The function fgets() reads up to num - 1 characters from the given file stream and dumps them
into str. fgets() will stop when it reaches the end of a line, in which case str will be terminated
with a newline. If fgets() reaches num - 1 characters or encounters the EOF, str will be null-
terminated. fgets() returns str on success, and NULL on an error.

e.g fgets(str, 79,fp);

fprintf

Syntax:
#include <stdio.h>
int fprintf( FILE *stream, const char *format, ... );
The fprintf() function sends information (the arguments) according to the specified format to the
file indicated by stream. fprintf() works just like printf() as far as the format goes. The return
value of fprintf() is the number of characters outputted, or a negative number if an error occurs.
An example:

char name[20] = "Mary";


FILE *out;
out = fopen( "output.txt", "w" );
if( out != NULL )
fprintf( out, "Hello %s\n", name );

fputc

Syntax:
#include <stdio.h>
int fputc( int ch, FILE *stream );

The function fputc() writes the given character ch to the given output stream. The return value is
the character, unless there is an error, in which case the return value is EOF.

fputs

Syntax:
#include <stdio.h>
int fputs( const char *str, FILE *stream );

The fputs() function writes an array of characters pointed to by str to the given output stream.
The return value is non-negative on success, and EOF on failure.

fread

Syntax:
#include <stdio.h>
int fread( void *buffer, size_t size, size_t num, FILE *stream );

The function fread() reads num number of objects (where each object is size bytes) and places
them into the array pointed to by buffer. The data comes from the given input stream. The return
value of the function is the number of things read...use feof() or ferror() to figure out if an error
occurs.

freopen

Syntax:
#include <stdio.h>
FILE *freopen( const char *fname, const char *mode, FILE *stream );
The freopen() function is used to reassign an existing stream to a different file and mode. After a
call to this function, the given file stream will refer to fname with access given by mode. The
return value of freopen() is the new stream, or NULL if there is an error.

fscanf

Syntax:
#include <stdio.h>
int fscanf( FILE *stream, const char *format, ... );

The function fscanf() reads data from the given file stream in a manner exactly like scanf(). The
return value of fscanf() is the number of variables that are actually assigned values, or EOF if no
assignments could be made.

fseek

Syntax:
#include <stdio.h>
int fseek( FILE *stream, long offset, int origin );

The function fseek() sets the file position data for the given stream. The origin value should have
one of the following values (defined in stdio.h):

fseek() returns zero upon success, non-zero on failure. You can use fseek() to move beyond a
file, but not before the beginning. Using fseek() clears the EOF flag associated with that stream.

fsetpos

Syntax:
Name Explanation
SEEK_SET Seek from the start of the file
SEEK_CUR Seek from the current location
SEEK_END Seek from the end of the file
#include <stdio.h>
int fsetpos( FILE *stream, const fpos_t *position );

The fsetpos() function moves the file position indicator for the given stream to a location
specified by the position object. fpos_t is defined in stdio.h. The return value for fsetpos() is zero
upon success, non-zero on failure.

ftell

Syntax:
#include <stdio.h>
long ftell( FILE *stream );

The ftell() function returns the current file position for stream, or -1 if an error occurs.
fwrite

Syntax:
#include <stdio.h>
int fwrite( const void *buffer, size_t size, size_t count, FILE *stream );

The fwrite() function writes, from the array buffer, count objects of size size to stream. The
return value is the number of objects written.

remove

Syntax:
#include <stdio.h>
int remove( const char *fname );

The remove() function erases the file specified by fname. The return value of remove() is zero
upon success, and non-zero if there is an error.

rename

Syntax:
#include <stdio.h>
int rename( const char *oldfname, const char *newfname );

The function rename() changes the name of the file oldfname to newfname. The return value of
rename() is zero upon success, non-zero on error.

rewind

Syntax:
#include <stdio.h>
void rewind( FILE *stream );

The function rewind () moves the file position indicator to the beginning of the specified stream,
also clearing the error and EOF flags associated with that stream.

You might also like