Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Professional C++ [eng].pdf
Скачиваний:
284
Добавлен:
16.08.2013
Размер:
11.09 Mб
Скачать

Chapter 14

Unfortunately, the printf() function knows nothing about the Muffin type and is unable to output an object of type Muffin. Worse still, because of the way the printf() function is declared, this will result in a run-time error, not a compile-time error (though a good compiler will give you a warning).

The best you can do with printf() is to add a new output() method to the Muffin class.

class Muffin

 

{

 

public:

 

string

getDescription() const;

void

setDescription(const string& inDescription);

int

getSize() const;

void

setSize(int inSize);

bool

getHasChocolateChips() const;

void

setHasChocolateChips(bool inChips);

 

void output();

protected:

 

string

mDescription;

int

mSize;

bool

mHasChocolateChips;

};

 

string Muffin::getDescription() const { return mDescription; }

void Muffin::setDescription(const string& inDescription) { mDescription = inDescription; }

int Muffin::getSize() const { return mSize; }

void Muffin::setSize(int inSize) { mSize = inSize; }

bool Muffin::getHasChocolateChips() const { return mHasChocolateChips; }

void Muffin::setHasChocolateChips(bool inChips) { mHasChocolateChips = inChips; }

void Muffin::output()

{

printf(“%s, Size is %d, %s\n”, getDescription().c_str(), getSize(), (getHasChocolateChips() ? “has chips” : “no chips”));

}

Using such a mechanism is cumbersome, however. To output a Muffin in the middle of another line of text, you’d need to split the line into two calls with a call to Muffin::output() in between, as shown here:

printf(“The muffin is “); myMuffin.output(); printf(“ -- yummy!\n”);

Overloading the << operator lets you output a Muffin just like you output a string — simply by providing it as an argument to <<. Chapter 16 covers the details of overloading the << and >> operators.

String Streams

String streams provide a way to use stream semantics with strings. In this way, you can have an inmemory stream that represents textual data. Such an approach can be useful in applications where multiple threads are contributing data to the same string, or where you want to pass a string around to

390

Demystifying C++ I/O

different functions, while retaining the current read position. String streams are also useful for parsing text, because streams have built-in tokenizing functionality.

The ostringstream and istringstream classes are used for writing and reading data to/from a string, respectively. They are both defined in the <sstream> header file. Because ostringstream and istringstream inherit the same behavior as ostream and istream, working with them is pleasantly similar.

The following simple program requests words from the user and outputs them to a single ostringstream, separated by the tab character. At the end of the program, the whole stream is turned into a string object using the str() method and is written to the console.

#include <iostream> #include <sstream>

using namespace std;

int main(int argc, char** argv)

{

ostringstream outStream; while (cin.good()) {

string nextToken;

cout << “Next token: “; cin >> nextToken;

if (nextToken == “done”) break; outStream << nextToken << “\t”;

}

cout << “The end result is: “ << outStream.str() << endl;

}

Reading data from a string stream is similarly familiar. The following function creates and populates a Muffin object (see earlier example) from a string input stream. The stream data is in a fixed format so that the function can easily turn its values into calls to the Muffin setters.

Muffin createMuffin(istringstream& inStream)

{

Muffin muffin;

//Assume data is properly formatted:

//Description size chips

string description; int size;

bool hasChips;

//Read all three values. Note that chips is represented

//by the strings “true” and “false”

inStream >> description >> size >> boolalpha >> hasChips; muffin.setSize(size); muffin.setDescription(description); muffin.setHasChocolateChips(hasChips);

return muffin;

}

391