Hello;
The downloaded version of problem, Ex8_09, does not deliver the correct output! So, you might suspect that the downloaded version differs from the textbook version and that difference accounts for the flaw. No! I've compared manually the downloaded source to that in the book and they are the same (human reliability: 80% :-).
I will show the statement which I suspect caused the failure and a correction I made which give the correct output. Then I have a question about precedence of operators which, I assert, accounts for the original flaw.
I wrap up my observations and questions below in the section marked, "Questions:".
Here is the flawed output that I got from the downloaded source. Note the flaw: that the array of names does not pair up properly with the ages of the people.
--------------------
Enter a first name or press Enter to end: Tom
Enter a second name: One
Enter Tom's age: 1
Enter a first name or press Enter to end: Bob
Enter a second name: Two
Enter Bob's age: 2
Enter a first name or press Enter to end: John
Enter a second name: Three
Enter John's age: 3
Enter a first name or press Enter to end:
The names you entered are:
Bob Two aged 1.

John Three aged 2.
aged 3.
Done!!
-------------------------
Here is the original logic which introduces the flaw in the function, listnames.
while(i<count && !names[i].empty())
cout << names[i] + " aged " + ages[i++] + '.' << endl;
Here is a modification which yields the desired result of pairing up persons with their age. Note that I simply ensure that the autoincrement of i happens after referencing the arrays with i :
while(i<count && !names[i].empty())
{
cout << names[i] + " aged " + ages[i] + '.' << endl;
i++;
}
Here is the output that my modification generates which is the desired output:
-------------------
Enter a first name or press Enter to end: Tom
Enter a second name: One
Enter Tom's age: 1
Enter a first name or press Enter to end: Bob
Enter a second name: Two
Enter Bob's age: 2
Enter a first name or press Enter to end: John
Enter a second name: Three
Enter John's age: 3
Enter a first name or press Enter to end:
The names you entered are:
Tom One aged 1.
Bob Two aged 2.
John Three aged 3.
Done!!
-------------------
Here's the loop which outputs the flawed results:
while(i<count && !names[i].empty())
cout << names[i] + " aged " + ages[

i++

] + '.' << endl;
I speculate that, in the downloaded source, the expression is evaluated in the order from right to left whereas the textbook version is performed left to right:
The flawed outcome I experienced would occur if the order of operation was as follows:
names[i] + (" aged " + ( ages[i++] + '.' ) ) //out give the flawed output I
//see.
And yet, the textbook presents output which asserts that the order of evaluation would be :
( ( (names[i]) + " aged " ) + ages[i++] + '.' ) //would give the desired
// output, but I don't get this.
Questions:
Does anyone dispute my interpretation that the actual behavior of the original program is to perform the several operations "+" in order from right to left, which caused flawed results? Try it yourself and see!
Author Horton displays correct output in the book from this same original program which give me flawed output. This asserts to me that his compiler interpreted his expression from left to right; while my program from the same source code evaluates from right to left and, consequently, outputs incorrect results?? This is entirely unreasonable, but seems to be happening anyway!
Is the order of operation for not determined? (Can the compiler can do the evaluation of the series of +'s in any order it wishes? in indeterminate order? Naw! Something is going on here! Could it have to do with overloading the + operator for strings????)
A further development:
The discussion of this program appears on p.475 of the book and suggests that the line in question can be replaced with this one:
cout << ((names[i].operator+(" aged ")).operator+(ages[i++])).operator+('.') << endl;
This replacement line will not compile for me and gives errors C2039 and c2228 and this message (What is this error and message trying to tell me?):
c:\beginning visual c plus plus examples\225905 code download\code from the book\ch8\ex8_09a\ex8_09a.cpp(21) : error C2039: '+' : is not a member of 'std::basic_string<_Elem,_Traits,_Ax>'
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
c:\beginning visual c plus plus examples\225905 code download\code from the book\ch8\ex8_09a\ex8_09a.cpp(21) : error C2228: left of '.+' must have class/struct/union
c:\beginning visual c plus plus examples\225905 code download\code from the book\ch8\ex8_09a\ex8_09a.cpp(21) : error C2228: left of '.+' must have class/struct/union
By the way, I'm using Microsoft Visual C++ 2008 Express Edition which seems to be part of this build:
Microsoft Visual Studio 2008
Version 9.0.30729.1 SP
I chose to disable pre-compiled headers and "#include "stdafx.h" does not appear in the Ex8_09.cpp source.
My headers are these in the source :
// Ex8_09.cpp
// Creating and joining string objects
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::getline;
// List names and ages
void listnames(string names[], string ages[], size_t count)
{
size_t i = 0;
cout << endl << "The names you entered are: " << endl;
while(i<count && !names[i].empty())
cout << ((names[i].operator+(" aged ")).operator+(ages[i++])).operator+('.') << endl;
}
...