How to emit a list separated by commas in YAML - c++

I have a 9 3x3 matrix of all zeroes. I am trying to output it in row major form so that it will look like.
covariance: 0,0,0,0,0,0,0,0,0,
I have tried
out1 << YAML::Key << "covariance";
out1 << YAML::Literal<< covariance[0][0]<< "," << covariance[0][1]... etc.
But i get :
covariance: 0
",": 0
what am I doing wrong?
note: I DO NOT want [0,0,0,0,0,0,0,0,0]. I would like it without the brackets

Build a string up, and then print it out:
std::stringstream value;
for (int i=0;i<N;i++) {
value << covariance[0][i];
if (i + 1 < N) {
value << ",";
}
}
YAML::Emitter out;
out << YAML::BeginMap;
out << YAML::Key << "covariance" << YAML::Value << value.str();
out << YAML::EndMap;
The point is that the value you're printing isn't a YAML list, it's just a plain string that happens to look a little bit like YAML. So you can't use
yaml-cpp to format it for you; you need to do that yourself.

Related

C++ display text left and right in same row

I want to output a whole formatted console line (80 characters) in C++.
It should look like this:
Some things on the left side some other on the right side
The data contains two iterator functions that return std::string and fixed texts. Something like this:
std::cout << (*some_iterator)->getID() << " some text:" << LOTSOFSPACES << (*some_other_iterator)->getName() << " some more text.";
Outcome should always be 80 characters.
I tried messing around with std::setw and std::setfill, std::left and std::right, using a stringstream and calculating the spaces I have to create. But nothing really works and most ideas just destroyed the output completely.
Any ideas? Unfortunately I am not allowed to use external libraries.
If you can tell for sure both parts are always less than 40 characters (or they can be split in two columns in any other way), you could do it like this:
std::string firstPart = (*some_iterator)->getID() + " some text:";
std::string secondPart = (*some_other_iterator)->getName() + " some more text.";
std::cout << std::setw(40) << std::left << firstPart
<< std::setw(40) << std::right << secondPart;
See it online
More versatile solution would be to simply calculate the spacing between strings and insert it manually. This doesn't require having columns of known length:
std::string firstPart = (*some_iterator)->getID() + " some text:";
std::string secondPart = (*some_other_iterator)->getName() + " some more text.";
std::size_t spacingSize = 80 - firstPart.length() - secondPart.length();
//Add some code to check if spacingSize is not negative!
std::cout << firstPart << std::string(spacingSize, ' ') << secondPart;
See it online
You can try to set the coursor at the position.
First you have to add library:
#include <windows.h>
Now you can use function:
COORD c;
c.X = x_coordinate;
c.Y = y_coordinate;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);

Setting precision of floating point number

Hello guys I am new in C++
I am trying to write the function to calculate the second moment of inertia and set the precision with 3 decimal places.
In the output does not apply the 3 decimal places in the first call but the following 4 calls does applied. Here is my codes , please help me find the error and if possible please explain some details thank you very much !
double beamMoment(double b, double h) //the function that calculating the second moment of inertia
{
double I; //variables b=base, h=height, I= second moment of inertia
I = b * (pow(h, 3.0) / 12); // formular of the second momeent of inertia
ofs << "b=" << b << "," << "h=" << h << "," << "I=" << I << setprecision(3) << fixed << endl;
ofs << endl;
return I;
}
int main()
{
beamMoment(10,100);
beamMoment(33, 66);
beamMoment(44, 88);
beamMoment(26, 51);
beamMoment(7, 19);
system("pause");
return 0;
}
The output in my text file is as follow :
b=10,h=100,I=833333
b=33.000,h=66.000,I=790614.000
b=44.000,h=88.000,I=2498730.667
b=26.000,h=51.000,I=287410.500
b=7.000,h=19.000,I=4001.083
You have to set stream precision before printing a number.
ofs << 5.5555 << setprecision(3) << endl; // prints "5.5555"
ofs << setprecision(3) << 5.5555 << endl; // prints "5.555"
Stream operators << and >> are, in fact, methods that can be chained. Let's say we have a piece of example java code like:
dog.walk().stopByTheTree().pee();
In C++, if we'd use stream operators, it'd look like:
dog << walk << stopByTheTree << pee;
Operations on dog objects are executed from left to right, and the direction of "arrows" doesn't matter. These method names are just syntactic sugar.
Look here for more details.

Why is my first ofstream output in my else block missing the fill character?

I'm using this code to output nodes of a huffman tree to a text file with a certain formatting. All the node outputs within the if block run as expected, but the first output in the else block is missing the '0' fill character after the "L:". It should output "L:076" but instead is outputting "L: 76". The cout looks correct but the text file isn't. All future loops through the else block output like they should, it's only the first loop that is missing the fill character. Here's a picture of my output
void preOrder(node* tree, std::ofstream& of) {
if (tree->label > 0) {
of << "I:" << tree->label << " ";
}
else {
std::cout.width(3);
std::cout << std::right;
std::cout.fill('0');
std::cout << int(tree->ch) << std::endl;
of << "L:";
of << of.fill('0');
of << std::right;
of << int(tree->ch);
of << " ";
return;
}
preOrder(tree->left, of);
preOrder(tree->right, of);
}
From cppreference.com:
The second form (2) sets fillch as the new fill character and returns the fill character used before the call.
"The second form" is the non-const version, that applies here. So my guess (I never used fill myself and I cannot compile your code as it is) would be that the call is correctly applied and then you put the old fill character (blank space presumably) to the stream, because you do:
of << of.fill('0');
Also, I noticed that you dont set the width of of.
Because you're hiding something naughty from us.
#include <iostream>
int main()
{
std::cout.width(3);
std::cout << std::right;
std::cout.fill('0');
std::cout << 3 << std::endl;
return 0;
}
Outputs 003 (live example).
Please provide an MCVE and I'll edit my answer to help you.

Non-persistent formatting of streams

What's the best way (if any) to format std::*stream output in localized manner, so that formatting changes in one location won't affect the use of that stream in other locations?
That is, I'd like to set format of the stream for a single statement, not for the remaining lifetime of the stream.
The following is just a rationale for asking the above question.
Suppose you print intensity in default floating point format:
ostringstream oss;
oss << "Intensity = " << intensity << "; ";
Then print coordinates with fixed 2 digits precision:
oss << "Point = (" << fixed << setprecision(2) << pt.x << ", " << pt.y << "); ";
then, 20 lines later, print ray direction in the same fixed 2 digits format:
oss << "Direction = (" << dir.x << ", " << dir.y << "); ";
A few months later add printing of luminosity in default floating point format somewhere between printing pt and printing dir:
oss << "Luminosity = " << lum << "; ";
Oops, lum will be printed in fixed 2 digits precision because you changed oss format 20 lines before, when printing pt. Now you have to recall what you've changed in oss and rewind it for printing lum.
Moreover, after fixing format for lum you'd get another problem: dir won't be printed in fixed 2 digits anymore...
Therefore I'd like to be able to format streams locally to avoid unnecessary dependencies.
You can simply save and restore stream format flags (see std::iosbase::flags()):
fmtflags oldflags = oss.flags();
// change current format flags
oss.flags(oldflags); // <<< restore to former state
If you don't like it straight forward as mentioned above, you could also use a proxy:
class local_ostream {
public:
friend template<typename T>
local_ostream& operator<<(local_ostream& los, const& T value) {
los.os_ << value;
return los;
}
local_ostream(std::ostream& os) : os_(os), oldflags_(os.flags()) {
}
~local_ostream() {
os_.flags(oldflags_);
}
private:
std::ostream& os_;
std::iosbase::fmtflags oldflags_;
};
And use as follows:
{ local_ostream los(oss);
los << "Point = (" << fixed << setprecision(2) << pt.x << ", " << pt.y << "); ";
} // previous formatting state is restored here

C++ const casting

I am trying to print the value of a const but it is not working. I am making a return to C++ after years so I know casting is a possible solution but I can't get that working either.
The code is as follows:
//the number of blanks surrounding the greeting
const int pad = 0;
//the number of rows and columns to write
const int rows = pad * 2 + 3;
const string::size_type cols = greeting.size() + pad * 2 + 2;
cout << endl << "Rows : " + rows;
I am trying to print the value of 'rows' without success.
You want:
cout << endl << "Rows : " << rows;
Note this has nothing to do with const - C++ does not allow you to concatenate strings and numbers with the + operator. What you were actually doing was that mysterious thing called pointer arithmetic.
You're almost there:
cout << endl << "Rows : " << rows;
The error is because "Rows : " is a string literal, thus is a constant, and generally speaking is not modified as you may think.
Going slightly further, you likely used + (colloquially used as a concatenation operation) assuming you needed to build a string to give to the output stream. Instead operator << returns the output stream when it is done, allowing chaining.
// It is almost as if you did:
(((cout << endl) << "Rows : ") << rows)
I think you want:
std::cout << std::endl << "Rows : " << rows << std::endl;
I make this mistake all the time as I also work with java a lot.
As others have pointed out, you need
std::cout << std::endl << "Rows : " << rows << std::endl;
The reason (or one of the reasons) is that "Rows : " is a char* and the + operator for char*s doesn't concatenate strings, like the one for std::string and strings in languages like Java and Python.