ostream outputting garbage

D

dev_15

Hi, i have the following program to display the input received
separated into any word that has Uppercase letters and all lowercase
words.

For the following input "Upper lower" i get the following
output on the console

Upper
0002A634lower
0002A634

I was expecting just

Upper
lower

Why am i getting the print of some memory address presumably, code
below:

using std::string;
using std::vector;
using std::cin;
using std::cout;
using std::eek:stream;
using std::endl;

bool IsUpper(const string& s);
ostream& Write(ostream& out, vector<string>& v);
vector<string> GetUpper(vector<string>& v);


int _tmain()
{
vector<string> vec;

string s;

while (cin >> s)
vec.push_back(s);

vector<string> Upper = GetUpper(vec);

cout << Write(cout, Upper);
cout << Write(cout , vec);

return 0;

}


ostream& Write(ostream& out, vector<string>& v)
{
for(vector<string>::size_type i =0; i!=v.size(); ++i)
{
out << v << endl;
}
return out;
}


vector<string> GetUpper(vector<string>& v)
{
vector<string> Upper;
vector<string>::iterator iter = v.begin();
while (iter != v.end())
{
if (IsUpper(*iter))
{
Upper.push_back(*iter);
iter = v.erase(iter);
}
else
{
++iter;
}
}
return Upper;

}

bool IsUpper(const string& s)
{
bool ret = false;
typedef string::size_type string_size;
string_size i = 0;

while (i != s.size() && (ret==false))
{
if (isupper(s))
ret = true;
++i;
}
return ret;
}
 
E

Erik Wikström

Hi, i have the following program to display the input received
separated into any word that has Uppercase letters and all lowercase
words.

For the following input "Upper lower" i get the following
output on the console

Upper
0002A634lower
0002A634

I was expecting just

Upper
lower

Why am i getting the print of some memory address presumably, code
below:

Please post the full program, including header files. We should only
have to copy & paste and compile, not modify.
cout << Write(cout, Upper);
cout << Write(cout , vec);

Write(cout, Upper);
Write(cout, vec);
 
D

dev_15

Sorry, header files now included


#include <iostream>
#include <string>
#include <vector>
#include <cctype>

using std::string;
using std::vector;
using std::cin;
using std::cout;
using std::eek:stream;
using std::endl;

bool IsUpper(const string& s);
ostream& Write(ostream& out, vector<string>& v);
vector<string> GetUpper(vector<string>& v);


int _tmain()
{
vector<string> vec;

string s;

while (cin >> s)
vec.push_back(s);

vector<string> Upper = GetUpper(vec);

cout << Write(cout, Upper);
cout << Write(cout , vec);

return 0;

}


ostream& Write(ostream& out, vector<string>& v)
{
for(vector<string>::size_type i =0; i!=v.size(); ++i)
{
out << v << endl;
}
return out;
}


vector<string> GetUpper(vector<string>& v)
{
vector<string> Upper;
vector<string>::iterator iter = v.begin();
while (iter != v.end())
{
if (IsUpper(*iter))
{
Upper.push_back(*iter);
iter = v.erase(iter);
}
else
{
++iter;
}
}
return Upper;

}

bool IsUpper(const string& s)
{
bool ret = false;
typedef string::size_type string_size;
string_size i = 0;

while (i != s.size() && (ret==false))
{
if (isupper(s))
ret = true;
++i;
}
return ret;
}
 
K

kasthurirangan.balaji

Sorry, header files now included

#include <iostream>
#include <string>
#include <vector>
#include <cctype>

using std::string;
using std::vector;
using std::cin;
using std::cout;
using std::eek:stream;
using std::endl;

bool IsUpper(const string& s);
ostream& Write(ostream& out, vector<string>& v);
vector<string> GetUpper(vector<string>& v);

int _tmain()
{
        vector<string> vec;

        string s;

        while (cin >>  s)
                vec.push_back(s);

        vector<string> Upper = GetUpper(vec);

        cout << Write(cout, Upper);
        cout << Write(cout , vec);

   return 0;

}

ostream& Write(ostream& out, vector<string>& v)
{
        for(vector<string>::size_type i =0; i!=v.size(); ++i)
        {
                out << v << endl;
        }
        return out;

}

vector<string> GetUpper(vector<string>& v)
{
        vector<string> Upper;
        vector<string>::iterator iter = v.begin();
        while (iter != v.end())
        {
                if (IsUpper(*iter))
                {
                        Upper.push_back(*iter);
                        iter = v.erase(iter);
                }
                else
                {
                        ++iter;
                }
        }
        return Upper;

}

bool IsUpper(const string& s)
{
        bool ret = false;
        typedef string::size_type string_size;
        string_size i = 0;

        while (i != s.size() && (ret==false))
        {
                if (isupper(s))
                        ret = true;
                ++i;
        }
        return ret;



}- Hide quoted text -

- Show quoted text -


Hope you have seen the correction. Repeating again

Write(cout, Upper);
Write(cout, vec);

Additional thoughts:

vector<string> Upper = GetUpper(vec);

After this, Upper is used only for printing. We can write it as

const vector<string> Upper(GetUpper(vec));


Also, the for loop inside Write could well be written as

for(vector<string>::size_type i =0, const vector<string>::size_type
j(v.size()); i!=j; ++i)

Thanks,
Balaji.
 
L

LR

dev_15 said:
Hi, i have the following program to display the input received
separated into any word that has Uppercase letters and all lowercase
words.

For the following input "Upper lower" i get the following
output on the console

Upper
0002A634lower
0002A634

I was expecting just

Upper
lower

Why am i getting the print of some memory address presumably, code
below:

I didn't look all that carefully at your code, but please consider:


std::eek:stream &operator<<(std::eek:stream &o,
const std::vector<std::string> &v);

and the line
std::cout << v;
probably produces some code that we can think of like this:
operator<<(std::cout, v);

whereas

std::eek:stream &write(std::eek:stream &o, const std::vector<std::string> &v);

and the line
std::cout << w(std::cout,v);
probably produces some code that we can think of like this:
operator<<(std::cout, write(std::cout,v));

In this case, the call to write will, if written like your code, write
out each element of v to std::cout and then return a reference to
std::cout. The call to operator<< will write out the 'value' of the
reference. I'm going to guess and say that somehow this reference
decays into a pointer of some kind. I'm probably not technically correct
about that.

You may want to play with this example and see if it clarifies things.

#include <iostream>

const int *p(std::eek:stream &o, const int &t) {
o << "*" << t << "*" << std::endl;
return &t;
}

int main() {
const int a = 55;
std::cout << "$" << p(std::cout, a) << "$" << std::endl;
std::cout << "#" << &a << "#" << std::endl;
}

LR
 
S

Salt_Peter

Hi, i have the following program to display the input received
separated into any word that has Uppercase letters and all lowercase
words.

For the following input "Upper lower" i get the following
output on the console

Upper
0002A634lower
0002A634

I was expecting just

Upper
lower

Why am i getting the print of some memory address presumably, code
below:

Because thats what you asked it to do.
using std::string;
using std::vector;
using std::cin;
using std::cout;
using std::eek:stream;
using std::endl;

bool IsUpper(const string& s);
ostream& Write(ostream& out, vector<string>& v);
vector<string> GetUpper(vector<string>& v);

int _tmain()

int main()
{
vector<string> vec;

string s;

while (cin >> s)
vec.push_back(s);

read input indefinitely?
vector<string> Upper = GetUpper(vec);

cout << Write(cout, Upper);
cout << Write(cout , vec);

Write(...) is being used like an operator, or trying to rather.
Instead of streaming the results of a function, doesn't it make sense
to stream the object(s), in this case the elements in that
std::vector?
Why don't you define an operator<< to stream std::vector< T > instead?
( staggered for readability and untested code )

#include <algorithm>
#include <iterator>

// operator<< for std::vector< std::string >
std::eek:stream&
operator<<( std::eek:stream& out,
const std::vector< std::string >& v )
{
std::copy( v.begin(),
v.end(),
std::eek:stream_iterator< std::string >(out, "\n") );
return out;
}

// then:

std::cout << Upper << vec; // so simple, clean

To further improve the above insertion op, template the operator so it
works with std::vectors of any type, not just std::string. Try it -
it'll be eye opening. An operator that can stream a vector of
anything, including a vector of types that don't exist yet (hint:
std::string already has an overload for op<<, same goes with all
primitive types).

template< typename T >
std::eek:stream&
operator<<( std::eek:stream& out,
const std::vector< T >& v )
{
...
}
return 0;

}

ostream& Write(ostream& out, vector<string>& v)
{
for(vector<string>::size_type i =0; i!=v.size(); ++i)
{
out << v << endl;
}
return out;

}

vector<string> GetUpper(vector<string>& v)
{
vector<string> Upper;
vector<string>::iterator iter = v.begin();
while (iter != v.end())
{
if (IsUpper(*iter))
{
Upper.push_back(*iter);
iter = v.erase(iter);
}
else
{
++iter;
}
}
return Upper;

}

bool IsUpper(const string& s)
{
bool ret = false;
typedef string::size_type string_size;
string_size i = 0;

while (i != s.size() && (ret==false))
{
if (isupper(s))
ret = true;
++i;
}
return ret;

}
 
J

James Kanze

I didn't look all that carefully at your code, but please consider:
std::eek:stream &operator<<(std::eek:stream &o,
const std::vector<std::string> &v);

That function doesn't exist. And if you actually define it, it
won't be found in a template.

The correct way of handling this is to wrap std::vector in a
user defined class.
 
L

LR

James said:
That function doesn't exist.

Oops. I should have made that clear.

And if you actually define it, it won't be found in a template.

Sorry, but I'm not sure that I understand what you meant by that. Could
you please expand on that?


The correct way of handling this is to wrap std::vector in a
user defined class.

Do you mean to wrap it if you're going to output it? Or create an
operator<< function? Why is wrapping the correct way?

TIA

LR
 
J

James Kanze

Oops. I should have made that clear.
Sorry, but I'm not sure that I understand what you meant by
that. Could you please expand on that?

That the operator won't be found, and won't be considered during
operator overload resolution, when << is invoked in a template,
e.g. in an ostream_iterator, for example. At least when
dependent lookup is involved (which will almost always be the
case) and the operator is only declared after the template has
been defined (which will depend on the order of includes, if the
operator is declared in an include).

For such operators to work correctly, they must be defined in a
namespace used in ADL. In the above case, std. And as a user,
you're not allowed to define such functions in the std
namespace. Formally, it's undefined behavior.

For a quick experiment, course, just to test something, I'll go
ahead and define the operator in std. In production code, of
course, you don't want to define it, even if you could.
Do you mean to wrap it if you're going to output it? Or
create an operator<< function? Why is wrapping the correct
way?

std::vector doesn't really have any established high level
semantics, which would define how you would output it. It's
sort of like the girders in a building: a structural detail of
the implementation, but having nothing directly to do with the
actual use of the building or the semantics of the program.
Within a program, you would normally wrap vector anyway, in an
application dependent class with application dependent
semantics. std::vector is not an abstraction of your
application. (I'm not sure that "wrap" is the correct word
here, since the class you define definitely adds to the
semantics.) There are doubtlessly some exceptions, when the
abstraction really is just an array; but since there is no
"standard" text representation of an array, you still have to
wrap it for output: you'll want different formats for output
depending on what the vector is being used for (e.g. a set of
values, a list of elements, a mathematical vector, etc.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top