Arrays, Strings and File I/O

Chapter 2 Weiss

Chapter 7 Lafore

 

The array data type in C++

•      Standard C++ arrays are stored in static RAM, unlike Java arrays which are stored dynamically.

•      Since arrays are stored in static RAM, their size must be declared at compile time.

•      C++ does support dynamically allocated arrays

–    The STL container vector is of this type

–    It is much more powerful and less error prone than standard arrays

•      Because standard arrays have been used in legacy code, will look at them as well as vectors.

•      In your coding, you will probably want to use vectors, but must also understand standard arrays.

 

Standard arrays

•      Declaring

–   int intArray [20];   declares an array of 20 elements

•      Accessing

–    Use loops to access the elements of an array just like in Java

•      Initializing  -  arrays can be initialized when they are defined

–   int daysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30,  31, 30, 31}

 

Vectors

•      A vector is really a dynamically allocated array of any type you want.

–    The system you are using determines how many elements the vector can hold.

•      It is a class template in the Standard Template Library

•      Because it is a template, the user declares what type it should be this way
  
vector <int> intArray;
  
vector<string> stringArray;

•      Because it is a class, it has both data members and member functions associated with it

•      Elements are added to the end of the vector using the member function pushback( )

 

The vector class

•      Some important member functions;

–    assume a vector vec has been declared

vec.pushback( elem) inserts an element at the end of the vector

vec.size( ) returns the actual number of elements in the vector

vec.capacity( ) returns the maximum possible number of elements without reallocation

vec.empty( ) returns true if the vector contains no elements

vec[idx] returns the element with the index idx (no range checking)

vec.at(idx)  throws range error exception if idx is out of range.

 

Example using a vector

•      #include <iostream>
#include <vector>
using namespace std;

    int main( )
{
    vector<int> coll;

        for (int i=1; i<=6; ++i)
       {   coll.push_back(i);    }


    for (int i=0; i<coll.size(); ++i)
          {    cout << coll[i] << ' ';    }   
    cout << endl;
}

 

Strings

•      There are two types of strings used in C++

–   In C (and often C++) strings are arrays of characters, terminated by a null character

•   C-strings are notoriously error prone, but are still much used in old C, C++ code

–   The standard C++ string class, which is much less error prone than C-strings

•   Normal operators like == !=, >, < are all overloaded so they work with the string class

•   The assignment statement = makes a deep copy, not a shallow copy

 

Standard C++ strings

•      Must #include <string>

•      Defining and initializing string objects

–   Strings can be initialized at the same time they are declared, or they can be left empty.

•    string s1(“Lots of snow”); 

•    string s2 = “more snow”;

•    string s3;   // empty string

•    s3 = s1;

•      Strings are concatenated with the + operator

–   You can concatenate string variables with string constants

–    s3 = s1 + “ is here.”

 

String I/O

•      When a string is read with cin, it will read until the first white space

cin >> s1;  // will read characters until it hits a white space

•      getline( ) handles input that contains embedded blanks or multiple lines.

–    The first argument is the stream object from which the input will come

–    getline(cin, s1);

  getline( ) is not a member function of the string class; i.e. it is not called  with an object object.funtion

 

Accessing characters in a string

•      You can treat a string object like an array of characters, and access individual characters with the [ ] operator.

–   The [ ] operator does not check range

•      If you want range check, use str.at(index)

•      The .at( ) member function is safer that [ ], and lets the compiler find errors for you

 

String member functions

•      s.length( )  – returns the length of the string (same as size( ))

•      s.substr(start, length) --returns a substring;

–    start is an index (an int), length an int

•      s.find(str)  -- returns the index where str is found

•      s.rase(start, length) -- removes the substring

•      s. insert(start, str) – inserts str at start

•      s.replace(start, length, str) – length is the number of characters to be replaced with str

•      s. append(num, char) – append num char at the end of the string

•      See page 303-311 of Lafore for examples

 

Disk file I/O

•      Many programs need to save data to disk, or read data from a disk file

•      Working with disk files requires a set of classes which are derived from other classes. 

–    We will look at only those classes you need to do simple file I/O

•      The classes you will need are declared in the fstream file, so you must #include <fstream> to use them

•      Classes: ifstream for input; ofstream for output;

•      You can read about file I/O on page 583 of the Lafore text.

 

Output to a file

•      You must declare an object of type ofstream
   
ofstream fileOut (“myData.txt”)

–   The object fileOut can be named anything

–   It will connect the file on disk to your program so it can be read.

–   If you need to include a path to the file, use the backslash.  (“c:\\path\\filename.txt”)

•      The ofstream object is then used just like cout with the insertion operator  <<
    fileOut << variableName;

•      Close the file when done  fileOut.close( );

 

Appending to a file

If the file exists, the above will overwrite the file.  If you want to append the file, you must specifically open the file to append (the default is to overwrite).  To do this use:

ofstream appendFile;    // declare the ofstream object

appendFile.open(“filename.txt”, ios::app);  // open the file for appending

 

 

 

Example of file output

 ofstream fileOut (“somefile.txt”);

 if (!fileOut)

 {     cout << “Cannot open somefile.dat”
             << endl;  }

   fileout << “radios “ << 39.95 << endl;
fileOut <<“toasters “ << 19.95 << endl;
fileOut <<“mixers “ << 24.95;

   fileout.close( );



Input of data from a file

•      You must declare an object of type ifstream
   
ifstream fileIn (“myData.txt”)

–   The object fileIn can be named anything

–   It will connect the file on disk to your program so it can be read.

•      The ifstream object (here fileIn) is then used just like cin with the extraction operator  >>
    fileIn >> variableName;

•      Check for end of file using the eof( ) member function:  while (!fileIn.eof( )) {  }

 

Example of file input

ifstream fileIn (“somefile.txt”);

if (!fileIn)   //check that file can be created
  cout << “Cannot open somefile.dat”
           << endl;

string item;   float  cost;  // declare variables

while(!fileIn.eof( ))
{   fileIn >> item  >>  cost;
     cout << item << “  “ << cost << endl;

}

 

Program we wrote in class

#include <iostream>

#include <fstream>

#include <string>

using namespace std;

 

void makeFile();    //prototypes

void readFile();

 

int main()

{          

    makeFile();

    readFile();

     cout << "Type q to quit: ";

     char quit;     cin >> quit;   

    return 0;

}  // end main

 

void makeFile()

{  

    ofstream fileOut("somefile.txt");

    if (!fileOut)

     {     cout << "Cannot open somefile.txt" << endl;  }

    fileOut << "radios " << 39.95 << endl;

    fileOut << "toasters " << 19.95 << endl;

    fileOut << "mixers " << 24.95;

    fileOut.close();

}  // end MakeFile

 

void readFile()

{  

    ifstream fileIn ("somefile.txt");

    if (!fileIn)   //check that file can be created

       cout << "Cannot open somefile.txt"  << endl;

    string item;  

    float  cost;  // declare variables

   

    while(!fileIn.eof( ))

    {   fileIn >> item  >>  cost;

        cout << item << "  " << cost << endl;

    }

}  //end readFile