I have the following function:
std::vector<double>residuals;
std::cout << Print_res(std::cout);
std::ostream& Print_res(std::ostream& os) const {
os << "\tresidual" << std::endl;
for (unsigned int i = 0 ; i < 22 ; i++) {
os << "\t\t" << residuals[i] << std::endl;
}
os << std::flush;
return os;
};
It prints the residuals correctly, but at the end of the output tags an address as follows:
2275
2279.08
2224.0835
0x80c5604
how do I fix this?
EDIT: after reading everyone's comments I replaced the call to the function Print_res with a std::copy as
std::copy(residuals.begin(), residuals.end(), std::ostream_iterator<double>(std::cout,"\n"));
and that did not print the address, so I presume there is something wrong in the way I have written the function.
std::cout << Print_res(std::cout);
This is not legal at global scope so the code that you have posted is not valid. If this statement were executed from, say, a function then Print_res would be called and then the return value of Print_res would also be streamed to std::cout. This is most likely not what you meant. You probably want just this:
Print_res(std::cout);
Your statement performs the equivalent of:
std::cout << std::cout;
In C++03 (which you must be using), std::cout has an operator void* (from std::basic_ios<char>) the result of which is what is being printed.
Related
I have some C++ console programs that display progress information on the last line of output, at regular intervals.
This progress line is cleared prior to writing the next real output (or updated progress information); this could be from a number of different places in the source, and I'm currently clearing the progress line on each one, e.g.:
cout << clearline << "Some real output" << endl;
...
cout << clearline << "Some other real output" << endl;
...
cout << clearline << setw(4) << ++icount << ") " << ... << endl;
...
cout << clearline << "Progress info number " << ++iprog << flush;
Here, 'clearline' is some (system dependent) string like "\r\33[2K" which clears the current last line.
I would prefer something cleaner, that localises source changes to the actual line that's going to be cleared, like simply:
cout << "Progress info number " << ++iprog << flush << defer_clearline;
where 'defer_clearline' causes the writing of 'clearline' to be deferred until just prior to the next cout output, wherever and whatever that happens to be. I then wouldn't need to use 'clearline' on all the other lines.
I thought it might be possible to do this if 'defer_clearline' is a manipulator, and/or using xalloc() and iword().
But I've not managed to get anything that works.
Is it possible to do this sort of thing, and if so how?
2020-12-30: edited to include missing 'flush's.
You can pretty easily setup an std::cout wrapper:
// Declare the empty struct clear_line and instantiate the object cls
struct clear_line { } cls;
class out {
private:
std::ostream &strm = std::cout;
bool is_next_clear = false;
public:
template <typename T>
out& operator<<(const T& obj) {
if(is_next_clear) {
strm << std::endl << std::endl << std::endl; // clear logic
is_next_clear = false;
}
strm << obj;
return *this;
}
out& operator<<(const clear_line& _) {
is_next_clear = true;
return *this;
}
};
This pretty simply stores an is_next_clear bool for whether or not the next regular output should be cleared. Then, in the general case (the templated operator<<()), we run your clear logic and flip the is_next_clear flag if applicable. Then just output as usual.
Then, the operator<<() is overloaded for the case of a clear_line object. So if one of those is sent, we know to flip the is_next_clear flag, but not actually output anything.
Here's an example use:
int main() {
out o;
o << "Some real output" << cls;
o << "Some other real output";
return 0;
}
Here it is in action: https://ideone.com/0Dzwlv
If you want to use endl, you'll need to add a special overload for it as this answer suggests: https://stackoverflow.com/a/1134467/2602718
// this is the type of std::cout
typedef std::basic_ostream<char, std::char_traits<char> > CoutType;
// this is the function signature of std::endl
typedef CoutType& (*StandardEndLine)(CoutType&);
// define an operator<< to take in std::endl
out& operator<<(StandardEndLine manip)
{
// call the function, but we cannot return its value
manip(strm);
return *this;
}
Live example: https://ideone.com/ACUMOo
I am trying to overload
<<
operator. For instance
cout << a << " " << b << " "; // I am not allowed to change this line
is given I have to print it in format
<literal_valueof_a><"\n>
<literal_valueof_b><"\n">
<"\n">
I tried to overload << operator giving string as argument but it is not working. So I guess literal
" "
is not a string. If it is not then what is it. And how to overload it?
Kindly help;
Full code
//Begin Program
// Begin -> Non - Editable
#include <iostream>
#include <string>
using namespace std;
// End -> Non -Editable
//---------------------------------------------------------------------
// Begin -> Editable (I have written )
ostream& operator << (ostream& os, const string& str) {
string s = " ";
if(str == " ") {
os << '\n';
}
else {
for(int i = 0; i < str.length(); ++i)
os << str[i];
}
return os;
}
// End -> Editable
//--------------------------------------------------------------------------
// Begin -> No-Editable
int main() {
int a, b;
double s, t;
string mr, ms;
cin >> a >> b >> s >> t ;
cin >> mr >> ms ;
cout << a << " " << b << " " ;
cout << s << " " << t << " " ;
cout << mr << " " << ms ;
return 0;
}
// End -> Non-Editable
//End Program
Inputs and outputs
Input
30 20 5.6 2.3 hello world
Output
30
20
5.6
2.3
hello
world
" " is a string-literal of length one, and thus has type const char[2]. std::string is not related.
Theoretically, you could thus overload it as:
auto& operator<<(std::ostream& os, const char (&s)[2]) {
return os << (*s == ' ' && !s[1] ? +"\n" : +s);
}
While that trumps all the other overloads, now things get really hairy. The problem is that some_ostream << " " is likely not uncommon, even in templates, and now no longer resolves to calling the standard function. Those templates now have a different definition in the affected translation-units than in non-affected ones, thus violating the one-definition-rule.
What you should do, is not try to apply a global solution to a very local problem:
Preferably, modify your code currently streaming the space-character.
Alternatively, write your own stream-buffer which translates it as you wish, into newline.
Sure this is possible, as I have tested. It should be portable since you are specifying an override of a templated function operator<<() included from <iostream>. The " " string in your code is not a std::string, but rather a C-style string (i.e. a const char *). The following definition works correctly:
ostream& operator << (ostream& os, const char *str) {
if(strcmp(str, " ") == 0) {
os << '\n';
} else {
// Call the standard library implementation
operator<< < std::char_traits<char> > (os, str);
}
return os;
}
Note that the space after std::char_traits<char> is necessary only if you are pre-c++11.
Edit 1
I agree with Deduplicator that this is a potentially dangerous solution as it may cause undesirable consequences elsewhere in the code base. If it is needed only in the current file, you could make it a static function (by putting it within an unnamed namespace). Perhaps if you shared more about the specifics of your problem, we could come up with a cleaner solution for you.
You might want to go with a user defined literal, e.g.
struct NewLine {};
std::ostream& operator << (std::ostream& os, NewLine)
{
return os << "\n";
}
NewLine operator ""_nl(const char*, std::size_t) // "nl" for newline
{
return {};
}
This can be used as follows.
int main(int, char **)
{
std::cout << 42 << ""_nl << "43" << ""_nl;
return 0;
}
Note three things here:
You can pass any string literal followed by the literal identifier, ""_nl does the same thing as " "_nl or "hello, world"_nl. You can change this by adjusting the function returning the NewLine object.
This solution is more of an awkward and confusing hack. The only real use case I can imagine is pertaining the option to easily change the behavior at a later point in time.
When doing something non-standard, it's best to make that obvious and explicit - here, the user defined literal indeed shines, because << ""_nl is more likely to catch readers' attention than << " ".
Let's say Ì have some class and added output functionality by overloading the left-shift operator:
struct Foo
{
int i = 1;
std::string s = "hello";
};
auto& operator<<(std::ostream& os, Foo const& foo)
{
os<<foo.i<<"\n";
os<<foo.s<<"\n";
return os;
}
What is a good way to indent the output?
Example: If I write
std::cout<<" "<<Foo{}<<std::endl;
the output is:
1
hello
Obviously, hello is not indented. Is there an easy way to indent the whole output (and not just the first element)?
You're serializing the Foo object right? So logically the serialized string of Foo is an implementation detail of Foo. You could write your own stream class or something along those lines but that is overengineering the problem.
auto& operator<<(std::ostream& os, Foo const& foo)
{
auto s = "\t" + std::to_string(foo.i) + "\n"
"\t" + foo.s;
return (os << s);
}
int main()
{
std::cout << Foo{} << "\n";
}
You can use the standard library manipulator setw to set the width of a field, which often results in indenting the text. Here's how you use it:
cout << std::setw(10) << "Viola!" << std::endl;
This will print the word "Viola!" indented by 4 spaces. Why 4 spaces? The parameter to setw() determines the entire width of the "field", which includes the 6 characters in "Viola!".
By default, setw() will align the text to the right, but can be made to align left by using another manipulator left. Here's an example:
cout << std::setw(10) << std::left << "Viola!" << std::endl;
This will output the string "Viola!" with no indentation, but with 4 spaces after it.
That should answer your original question about a good way to indent, and setw() is not just a good way, but the standard way.
The second question asks about how to have persistent indentation, and the answer is that there is not an easy way. The easiest approach is to add the call to setw() (or whichever indentation method that you use) in each of the calls to cout.
In addition to those answers, you should consider replacing the use of "\n" in your calls to cout with a call to endl. endl is the "end of line" manipulator, and makes your code work properly with any output stream. The code would look like this:
auto& operator<<(std::ostream& os, Foo const& foo)
{
os << foo.i << std::endl;
os << foo.s << std::endl;
return os;
}
ostream& operator<<(ostream& os, const PT& p)
{
os << "(" << p.x << "," << p.y << ")";
}
PT is a structure and x , y are its members.
Can someone please explain what exactly the above line does. Can't the desired text be printed using cout?
I came across this snippet of code from this site.
It's a custom overload for operator<<.
It means you can do this:
PT p = ...;
std::cout << p << "\n";
or this:
PT p = ...;
std::stringstream ss;
ss << p << "\n";
std::cout << ss;
or lots of other useful stuff.
However, it should be noted that the code you quoted won't work properly. It needs to return os.
This provides a method of outputting the PT. Now, you can use this:
PT p;
std::cout << p;
This gets translated into a call of
operator<< (std::cout, p);
That matches your overload, so it works, printing the x and y values in brackets with less effort on the user's part. In fact, it doesn't have to be cout. It can be anything that "is" a std::ostream. There are quite a few things that inherit from it, meaning they are std::ostreams as well, and so this works with them too. std::ofstream, for file I/O, is one example.
One thing that the sample you found doesn't do, but should, though, is return os;. Without doing that, you can't say std::cout << p << '\n'; because the result of printing p will not return cout for you to use to print the newline.
It allows the << operator to append the PT object to the stream. It seems the object has elements x and y that are added with a comma separator.
This operator << overloading for outputing object of PT class .
Here:
ostream& operator<<(ostream& os, const PT& p)
First param is for output stream where p will be appended.
It returns reference to os for chaining like this:
cout << pt << " it was pt" << endl;
I define this structure:
struct s_molecule
{
std::string res_name;
std::vector<t_particle> my_particles;
std::vector<t_bond> my_bonds;
std::vector<t_angle> my_angles;
std::vector<t_dihedral> my_dihedrals;
s_molecule& operator=(const s_molecule &to_assign)
{
res_name = to_assign.res_name;
my_particles = to_assign.my_particles;
my_bonds = to_assign.my_bonds;
my_angles = to_assign.my_angles;
my_dihedrals = to_assign.my_dihedrals;
return *this;
}
};
and these structures:
typedef struct s_particle
{
t_coordinates position;
double charge;
double mass;
std::string name;
std::vector<t_lj_param>::iterator my_particle_kind_iter;
s_particle& operator=(const s_particle &to_assign)
{
position = to_assign.position;
charge = to_assign.charge;
mass = to_assign.mass;
name = to_assign.name;
my_particle_kind_iter = to_assign.my_particle_kind_iter;
return *this;
}
} t_particle;
struct s_bond
{
t_particle * particle_1;
t_particle * particle_2;
std::vector<t_bond_param>::iterator my_bond_kind_iter;
s_bond& operator=(const s_bond &to_assign)
{
particle_1 = to_assign.particle_1;
particle_2 = to_assign.particle_2;
my_bond_kind_iter = to_assign.my_bond_kind_iter;
return *this;
}
};
and then in my code I return a pointer to an s_molecule (typedef'd to t_molecule, but still).
Using this pointer I can get this code to work:
for (unsigned int i = 0;
i < current_molecule->my_particles.size();
i++)
{
std::cout << "Particle "
<< current_molecule->my_particles[i].name << std::endl
<< "Charge: "
<< current_molecule->my_particles[i].charge << std::endl
<< "Mass: "
<< current_molecule->my_particles[i].mass << std::endl
<< "Particle Kind Name: "
<< (*current_molecule->my_particles[i].my_particle_kind_iter).atom_kind_name
<< std::endl
<< "x: " << current_molecule->my_particles[i].position.x
<< " y: " << current_molecule->my_particles[i].position.y
#ifdef USE_3D_GEOM
<< "z: " << current_molecule->my_particles[i].position.z
#endif
<< std::endl;
}
If I replace it with:
for (std::vector<t_particle>::iterator it = current_molecule->my_particles.begin();
it !=current_molecule->my_particles.end();
it++)
{
std::cout << "Particle "
<< (*it).name << std::endl
<< "Charge: "
<< (*it).charge << std::endl
<< "Mass: "
<< (*it).mass << std::endl
<< "Particle Kind Name: "
<< (*(*it).my_particle_kind_iter).atom_kind_name
<< std::endl
<< "x: " << (*it).position.x
<< " y: " << (*it).position.y
#ifdef USE_3D_GEOM
<< "z: " << (*it).position.z
#endif
<< std::endl;
}
I now get nasty segfaults...
Not to put too much here, but I'm also getting segfaults when I tried to do this:
std::cout << "Bond ATOMS : "
<< (*current_molecule).my_bonds[0].particle_1->name
<< std::endl
Again, current_molecule is a pointer to a s_molecule structure, which contains arrays of structures, which in turn either directly have vars or are pointers. I can't get these multiple layers of indirection to work. Suggestions on fixing these segfaults.
FYI I'm compiling on Linux Centos 5.4 with g++ and using a custom makefile system.
#sbi Thanks for the good advice! I believe you are right -- the assignment overloaded operator is unnecessary and should be scrapped.
I've followed the approach of commenting out stuff and am very confused. Basically in the function that passes the pointer to my particular molecule to the main function to print, I can see all the data in that molecule (bonds, particles, name, etc) perfectly, printing with cout's.
Once I pass it to the main as a ptr, if I use that ptr with an iterator I get a segfault. In other words. Also for some reason the bond data (which I can freely print in my funct that returns to the pointer) also segfaults if I try to print it, even if I use the [] to index the vector of bonds (which works for the particle vector).
That's the best info I can give for now.
A wild guess: Are you using shared libraries. I remember having difficulties passing STL-containers back and forth across shared library boundaries.
Jason (OP) was asked in a comment by David Rodríguez:
Are you returning a pointer to a local variable?
Jason answered:
No its a ptr to a class variable. The class is very much in existence (it contains the function that returns the molecule).
Unless you're talking of a true class variable (qualified as static), the fact that the class exists doesn't have much to do with it. Instances of a class exist, and they might have ceased to exist even if you just called a function on them.
As such, the question is:
Does the instance of the class that returned the pointer current_molecule still exist?
Or is current_molecule qualified as static, i.e. being a true class variable?
If the answer to both questions is "no", you're in Undefined County.
At this point, it becomes very important that you post source code that can be used by us here to actually reproduce the problem; it might well be located in source you aren't showing us.
Again, this issue was answered here:
Weird Pointer issue in C++
by DeadMG. Sorry for the double post.