// simple String output
ostream & operator<<(ostream & os, const String & st)
{
os << st.str;
return os;
}
// quick and dirty String input
istream & operator>>(istream & is, String & st)
{
char temp[String::CINLIM];
is.get(temp, String::CINLIM);
if (is)
st = temp;
while (is && is.get() != '\n')
continue;
return is;
}
The overloaded >> operator provides a simple way to read a line of keyboard input into a String object. It assumes an input line of String::CINLIM or fewer characters and discards any characters beyond that limit. Keep in mind that the value of an istream object in an if condition evaluates to false if input fails for some reason, such as encountering an end-of-file condition, or in the case of get(char *, int), reading an empty line.
Listing 12.6 exercises the String class with a short program that lets you enter a few strings. The program has the user enter sayings, puts the strings into String objects, displays them, and reports which string is the shortest and which comes first alphabetically.
Listing 12.6. sayings1.cpp
// sayings1.cpp -- using expanded String class
// compile with string1.cpp
#include
#include "string1.h"
const int ArSize = 10;
const int MaxLen =81;
int main()
{
using std::cout;
using std::cin;
using std::endl;
String name;
cout <<"Hi, what's your name?\n>> ";
cin >> name;
cout << name << ", please enter up to " << ArSize
<< " short sayings
String sayings[ArSize]; // array of objects
char temp[MaxLen]; // temporary string storage
int i;
for (i = 0; i < ArSize; i++)
{
cout << i+1 << ": ";
cin.get(temp, MaxLen);
while (cin && cin.get() != '\n')
continue;
if (!cin || temp[0] == '\0') // empty line?
break; // i not incremented
else
sayings[i] = temp; // overloaded assignment
}
int total = i; // total # of lines read
if ( total > 0)
{
cout << "Here are your sayings:\n";
for (i = 0; i < total; i++)
cout << sayings[i][0] << ": " << sayings[i] << endl;
int shortest = 0;
int first = 0;
for (i = 1; i < total; i++)
{
if (sayings[i].length() < sayings[shortest].length())
shortest = i;
if (sayings[i] < sayings[first])
first = i;
}
cout << "Shortest saying:\n" << sayings[shortest] << endl;;
cout << "First alphabetically:\n" << sayings[first] << endl;
cout << "This program used "<< String::HowMany()
<< " String objects. Bye.\n";
}
else
cout << "No input! Bye.\n";
return 0;
}
Note
Older versions of get(char *, int) don’t evaluate to false upon reading an empty line. For those versions, however, the first character in the string is a null character if an empty line is entered. This example uses the following code:
if (!cin || temp[0] == '\0') // empty line?
break; // i not incremented
If the implementation follows the current C++ Standard, the first test in the if statement detects an empty line, whereas the second test detects the empty line for older implementations.
The program in Listing 12.6 asks the user to enter up to 10 sayings. Each saying is read into a temporary character array and then copied to a String object. If the user enters a blank line, a break statement terminates the input loop. After echoing the input, the program uses the length() and operator<() member functions to locate the shortest string and the alphabetically earliest string. The program also uses the subscript operator ([]) to preface each saying with its initial character. Here’s a sample run:
Hi, what's your name?
>> Misty Gutz
Misty Gutz, please enter up to 10 short sayings
1: a fool and his money are soon parted
2: penny wise, pound foolish
3: the love of money is the root of much evil
4: out of sight, out of mind
5: absence makes the heart grow fonder
6: absinthe makes the hart grow fonder
7:
Here are your sayings:
a: a fool and his money are soon parted
p: penny wise, pound foolish
t: the love of money is the root of much evil
o: out of sight, out of mind
a: absence makes the heart grow fonder
a: absinthe makes the hart grow fonder
Shortest saying:
penny wise, pound foolish
First alphabetically:
a fool and his money are soon parted
This program used 11 String objects. Bye.
Things to Remember When Using new in Constructors
By now you’ve noticed that you must take special care when using new to initialize pointer members of an object. In particular, you should do the following:
• If you use new to initialize a pointer member in a constructor, you should use delete in the destructor.
• The uses of new and delete should be compatible. You should pair new with delete and new [] with delete [].