Note 2: String and File Reading and Writing

 

String:

A string is any group of characters enclosed in quotation marks, such as ¡°computer science¡±.  It is also character array with ¡®\0¡¯ at last element of array.

 

Example:

char   str[17] = ¡°computer science¡±;

same as

char   str[17] = {¡®c¡¯,  ¡®o¡¯, ¡¯m¡¯, ¡®p¡¯, ¡®u¡¯, ¡®t¡¯, ¡®e¡¯, ¡®r¡¯, ¡® ¡®, ¡®s¡¯, ¡®c¡¯, ¡®i¡¯, ¡®e¡¯, ¡®n¡¯, ¡®c¡¯, ¡®e¡¯, ¡®\0¡¯};  

 

Memory picture:

str

c

o

m

p

u

t

e

r

 

s

c

i

e

n

c

e

\0

 

 

Reading String:

First, prepare room for storage of a string by declaring a char array with the size of elements, as follows:

 

            char  str[10];

 

The easiest way to read a string into str is to read the characters into the elements one at a time and then to inert the null character (¡®\0¡¯) at the end.  Other way to read a string into str is using the extraction operator as follows:

 

            cin >> str;

 

It has two restrictions for reading strings. 

1.      The extraction operator defines a string as being delimited by white space.  When reading a string, >> skips all leading blanks, tabs, and newline characters.  Then the extraction operator reads all the characters up to the next blank, tab, or newline character, stopping with the input buffer pointer indicating the subsequent white space character.  This is the reason that we can only use >> to read a single word.

2.      The array of characters must be large enough to hold the longest possible string plus one extra element for the null character.

 

Other way of reading string:

char   ch, str[81];                           //Declaring the char variable and char array

 

cin.get(ch);                                    //Read one character and stored in ch

cin.get(str, 81);                              //Read a string which less than 81 characters

cin.getline(str, 81);                        //Read a string which less than 81 characters

getline(cin, str, 81);                       //Read a string which less than 81 characters

When reading a string from input buff more than once, should flush buffer first before reading another string from input buff to avoid input mistake.

 

Flush buffer:

cin.ignore(256, ¡®\n¡¯);                        //Flush buffer for Visial C++

fflush( );                                            //Flush buffer for C lanuage             

 

 

String Function:

The C++ has several build in string function; if you want to use those functions in the program, you have to include the header file, as shown:

 

            #include <string.h>

 

String Concatenation Function:

strcat (ToS, FromS);

 

It is joining two strings to form another.  It also has two requirements as following:

  1. The first parameter to the strcat function, such as ToS, must be a variable string (an array).
  2. The array that stores the first string, such as ToS, must be large enough to hold the concatenated string (that is, both the first and the second string together).

 

String Compare Function:

strcmp (s1, s2);

 

It compares the first parameter string (s1) and the second parameter string (s2).  If the s1 is less than the s2, function returns a negative integer.  If the s1 is equal to the s, the function returns a zero.  If the s1 greater than the s2, the function returns a positive integer.

 

String Copy Function:

strcpy (ToS, FromS);

 

It copies the string in FromS to ToS.  The programmer must ensure that ToS has enough room for the string.  Unpredictable results can occur if ToS is not sufficiently large.

 

String Length Function:

strlen (S);

 

The function returns the length of its string parameter.  The length is the number of characters (other than ¡®\0¡¯) in the string or the position of the null character in its storage as a value of type size_t.

 

 

 

Summary of four string functions:

Function

Action

Returns

strcat (ToS, FromS)

Concatenate string FromS onto the end of string ToS

ToS

strcmp (s1, s2)

Compare lexically strings s1 and s2

s1 < s2, negative integer

s1 = s2, 0

s1 > s2, positive integer

strcpy (ToS, FromS)

Copy string FromS into string ToS

ToS

strlen (S)

Length of string S

Length of S

 

 

String example:

In this example, read a whole number as string, and then pass as argument to a function that convert character numbers to the integer number; then stored in the integer variable and return it.

 

Source Code:

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//Header File

#include<iostream.h>

#include<string.h>

 

//Function Prototype

float  convert(char []);

 

//Main Routine

int main(void)

{

            char   str[80], answer;

            float   num;

 

            do

            {

                        cout << "Enter a whole number to be convert: ";

                        cin >> str;

 

                        num = convert(str);

 

                        cout << "Input character string is: " << str << endl;

                        cout << "Converted number is: " << num << endl << endl;

                        cout << "Do you want to convert the number again? \n¡±;

                        cout << ¡°(Y or y for YES, other for NO)\n";

                        cin >> answer;

                        cout << endl;

            }while (answer = = 'Y' || answer = = 'y');

           

return 0;

}

 

//Convert Function

float   convert(char str[])

{

            int     index, i;

            float   num=0;

             

            index = strlen(str);

            for(i = 0; i < index; i++)

            {

                        num *= 10;

                        num += (str[i] - '0');   //Convert string to number

            }

            return num;

}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

Processing File:

We have obtained data by assignments or by reading interactively and have presented information on the screen or printer.  It is easy to store and retrieve large amounts of the data in a file on disk.  In this section, it will show the methods that to process files and to format input and output.

 

File I/O:

A text file is a file of characters.  We can create and look at such a file with a text editor or word processor (Word Pad or Note Pad).  We read from and write to text files with streams of characters.

 

In C++, the base class for stream I/O operations is ios.  The subclasses istream and ostream are for input and output streams, respectively.  The operator >> is a member of istream, and << is an operator in ostream.  The standard input stream cin is an istream object; and cout, the standard output stream, is an instantiation of the ostream class.  These standard streams are available for interactive input and output when we include iostream.h.

 

Input and output are not interactive but involve disk files.  To use external text files, we include the header file fstream.h.  This header file includes iostream.h for basic stream I/O and contains specifications for several classes, among them; class ifstream for accessing input files and class ofstream for output files.

 

 

 

Some classes in the inheritance hierarchy for stream I/O:

Class

Description

Header File

ios

stream I/O base class

iostream.h

istream

input stream class

iostream.h

ostream

output stream class

iostream.h

ifstream

input file access

fstream.h (includes iostream.h)

ofstream

output file access

fstream.h (includes iostream.h)

 

To associate a stream variable (such as infile) with a disk file (such as raw.dat) and to open the file for reading, we declare infile to be an object in ifstream.

           

            ifstream   infile(¡°raw.dat¡±);

 

If outfile is to be the stream variable corresponding to the disk file process.dat, we declare

 

            ofstream  outfile(¡°process.dat¡±);

 

If a file opens successfully, the symbolic name for the file, such as infile or outfile, evaluates to a nonzero number.  If we cannot open the file, the variable is zero.  We should check for proper opening immediately.  The function assert makes an assertion that a boolean expression should be true.  We make the following assertion:

 

            assert(infile);

 

If the file does not open properly so that infile is zero (False), the computer aborts the program after displaying an error message, such as follows:

 

            Assertion failed: infile, file testing.cpp, line 12

 

To use assert, we include assert.h.  The following segment shows the steps of opening the two files:

            #include <fstream.h>

            #include <assert.h>

            :

            ifstream   infile (¡°raw.dat¡±);

            assert (infile);

 

            ofstream   outfile (¡°process.dat¡±);

            assert (outfile);

 

Read and Write File:

We can use the extraction (>>) and insertion (<<) with the file object instead of cin and cout, respectively.  For example, if num is an int variable, we can write num¡¯s value to the output file object, outfile, with

 

            outfile << num;

 

Similarly, if infile is a file of integers, we can read a value into num from infile with the following statement:

 

            infile >> num;

 

When reading the file, we can test if there has been an attempt to read beyond the end of the input stream with the ios class method eof.  There are several ways to check the end of file for loop condition as following:

 

            while (infile.eof ( ))

            while (infile.peek ( ) = = EOF)

            while (infile)

 

Closing and Opening Files:

A file is automatically closed when the function in which it is declared ends.  We can explicitly close a file using the class operation close, such as follows:

 

            infile.close ( );

            outfile.close ( );

 

To associate an input stream object with a disk file and open that file, we use the open class method with the file name as a parameter, such as follows:

 

            ifstream   infile;

            :

            infile.open (¡°raw.dat¡±);

            assert (infile);

 

It also can process the same type of data from two different files, junior.dat and senior.dat.  We can instantiate infile as an ifstream object associated with junior.dat.  After processing this file, we close junior.dat.  Then we open senior.dat and associate the new input file with infile, as following:

 

            ifstream   infile (¡°junior.dat¡±);

            assert (infile);

            :

            infile.close ( );

            infile.open (¡°senior.dat¡±);

            assert (infile);

            :