Accelerated C++ Solution to Exercise 5-0 (Part 2 / 3)

This is Part 2 of the 3-part Solution to Exercise 5-0.

Exercise 5-0 (Part 2 / 3)

This is a very simple program with the purpose of splitting a line of text (i.e. a input string) into words (i.e. an output vector<string>).

The Problem

Start from scratch, we need to write a program that is able to read in a line of text, and be able to split it into words. The full description and explanation of the program can be found in Chapter 5 of the book.

Solution Strategy

The text book sample program for this (part 2) exercise is fairly simple. It only requires 3 files which I can group into a small project as usual – I will describe this in the Project section below.

There is also one core learning from this chapter regarding sequential container processing using either (1) index, or (2) iterator. Both methods are effectively the same. e.g. assuming v is a vector<string>, the two following codes have the same effect (of displaying container elements to the output console).

Sequential Container Processing with Index:

        for (vector<string>::size_type i = 0; i != v.size(); ++i)
            cout << v[i] << endl;

Sequential Container Processing with Iterator:

        for (vector<string>::const_iterator iter = v.begin(); iter != v.end(); ++iter)
            cout << (*iter) << endl;

Remark

As the Author mentioned in the book, however:

  • Index is good for random container processing, whereas
  • Iterator is good for sequential container processing.

It is always a good idea to bear this in mind.

The Project

This is what the management tree looks like in Code::Block:

Acpp5p0p2MgntTree

C++ Source Files

  • main.cpp – this is the first program that is run during the implementation phase.
  • split.cpp – contains the split function.

C++ Header Files

  • split.h – declare the functions in the source file split.cpp.

Source Files

main.cpp

#include <iostream>  // cin, cout, endl, getline
#include <vector>    // vector
#include <string>    // string
#include "split.h"   // split

using std::vector;
using std::string;
using std::cin;
using std::cout;
using std::endl;
using std::getline;

// (5.7/90)
int main()
{
    string s;

    // read and split each line of input
    while (getline(cin, s))
    {
        vector<string> v = split(s);

        // write each word in v
        for (vector<string>::const_iterator iter = v.begin(); iter != v.end(); ++iter)
            cout << (*iter) << endl;
    }
    return 0;
}

split.cpp

#include <string>    // string
#include <vector>    // vector
#include <cctype>    // isspace

using std::vector;
using std::string;
using std::isspace;

// scan a string of texts, split into words, return a vector that contains these words.
// (S5.6/88)
vector<string> split(const string& s)
{
    vector<string> ret;
    typedef string::size_type string_size;
    string_size i = 0;

    // invariant: we have processed characters original value of [i, i)
    while (i != s.size() )
    {
        // ignore leading blanks
        // invariant: characters in range [original i, current i)
        while (i != s.size() && isspace(s[i]))
            ++i;

        // find end of next word
        string_size j = i;

        // invariant: none of the characters in range [original j, current j) is a space
        while (j != s.size() && !isspace(s[j]))
            ++j;

        // if we found some non-whitespace characters
        if (i != j)
            // copy from s starting at i and taking j - i chars
            ret.push_back(s.substr(i, j - i));
            i = j;
    }
    return ret;
}

Header Files

split.h

#ifndef GUARD_SPLIT_H
#define GUARD_SPLIT_H

#include <vector>
#include <string>

std::vector<std::string> split(const std::string&);

#endif // GUARD_SPLIT_H

Test Results

I am going to enter the following 3 lines when the program starts up. I should see the individual words (separated by empty space) displayed on the screen straight after I hit the enter button.

  1. Hello world, how are we today?
  2. Nice, so the program works!
  3. Bye bye
Hello world, how are we today?
Hello
world,
how
are
we
today?
Nice, so the program works!
Nice,
so
the
program
works!
Bye bye
Bye
bye
^Z

The program works as expected!

Reference

Koenig, Andrew & Moo, Barbara E., Accelerated C++, Addison-Wesley, 2000