How to align output? - c++

How to align the output?
I tried this
for(int x = 0; i<5; i++)
cout<<a[x]<<setw(5)<<"|"<<setw(5)<<b[x]<<endl;
If all of a have same char length then the output like this
frd | hehe
asd | hoho
.....
.....
But if not have same length
frd | hehe
asdfg | hohoo
How to solve this?

In your suggested code:
cout<<a[x]<<setw(5)<<"|"<<setw(5)<<b[x]<<endl;
you have two problems that are leading to misalignment. (1) you have not provided any width for a[x] so it will be output without any adjustment; and (2) depending on the alignment you seek, the default justification when a width is specified for std::cout will be right justified.
(additionally, as noted in my comment, in your first example, a[0] and a[1] cannot have the same length as the example suggests. There "frd " is stored with additional whitespace (or "asd\b" is stored with an embedded backspace) otherwise the output of "a[x]|" would be aligned.)
To provide alignment for the output of both a and b, you must specify, at minimum, the width of a[x] with std::setw(n). Further, unless you want a[x] aligned to the right of the field created by std::setw(5), you must control the justification by setting std::ios_base::fmtflags with std::setiosflags(std::ios_base::left) (or simply std::left). See std::setiosflags.
When you set a format flag for the stream, you are setting bits in a Bitmap type that will remain set after the current call to std::cout completes. So to tidy up after yourself and restore the flag state of the stream to default, you either (1) have to save the fmtflags for the stream with by capturing all flags with std::ios_base::fmtflags or (2) you must reset the individual flag you set with std::resetiosflags(...).
So if I understand your question and your request for alignment (though it is unclear how you want b[x] aligned), you could align both a and b with left justification by:
std::cout << "left justified output (both a & b)\n\n";
for (size_t i = 0; i < a.size(); i++)
std::cout << std::left << std::setw(5)
<< a[i] << " | " << b[i] << '\n';
or you could align a with left justification and then restore the default flag state letting b be output with default (right) justification, e.g.
std::cout << "\nleft justified output for a, default for b\n\n";
for (size_t i = 0; i < a.size(); i++)
std::cout << std::left << std::setw(5)
<< a[i] << " | " << std::resetiosflags(std::ios_base::left)
<< std::setw(5) << b[i] << '\n';
Putting that altogether in an example, you could do:
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
int main (void) {
std::vector<std::string> a = { "frd", "asdfg", "asd", "quack" },
b = { "hehe", "hohoo", "haloo", "hack" };
std::cout << "left justified output (both a & b)\n\n";
for (size_t i = 0; i < a.size(); i++)
std::cout << std::left << std::setw(5)
<< a[i] << " | " << b[i] << '\n';
std::cout << "\nleft justified output for a, default for b\n\n";
for (size_t i = 0; i < a.size(); i++)
std::cout << std::left << std::setw(5)
<< a[i] << " | " << std::resetiosflags(std::ios_base::left)
<< std::setw(5) << b[i] << '\n';
}
Example Use/Output
$ ./bin/setwstring
left justified output (both a & b)
frd | hehe
asdfg | hohoo
asd | haloo
quack | hack
left justified output for a, default for b
frd | hehe
asdfg | hohoo
asd | haloo
quack | hack
Note: if you want to make multiple changes to flags within the course of an output operation and then restore ALL format flags to their original state, you can use:
std::ios_base::fmtflags f = std::cout.flags (); // save ios_base flags
// do output, set flags as desired
std::cout.flags (f); // restore saved flags
Let me know if this addresses the alignment you were attempting to achieve.

You can change the setw(#) with any number you need.
#include<iostream>
#include<iomanip>
#include<string>
using namespace std;
int main()
{
string a[5] = {"afdfadsf","ggrggeee","fdsafsda","erererefdsfd","sdfdsfdffdf"};
string b[5] = {"fdsfdsfd", "fdsfdsaffdf","fdsfsadfdfd","rererrefdfd","zzzzzzzfdfd"};
for(int i = 0; i<5; i++)
cout << left << setw(15) << a[i] << left << setw(15) << b[i] << endl;
}

Try using printf. Seriously, it works.
eg:
#include <cstdio>
int main() {
printf("%-10s | %10s\n", "asd", "asdad");
printf("%-10s | %10s\n", "asd", "adad");
printf("%-10s | %10s\n", "adsada", "adad");
printf("%-10s | %10s\n", "addasda", "adad");
printf("%-10s | %10s\n", "asdsd", "dad");
printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", "asdsd", "dad");
printf("%-10s | %-10s\n", "asd", "asdad");
printf("%-10s | %-10s\n", "asd", "adad");
printf("%-10s | %-10s\n", "adsada", "adad");
printf("%-10s | %-10s\n", "addasda", "adad");
printf("%-10s | %-10s\n", "asdsd", "dad");
}
Gives
asd | asdad
asd | adad
adsada | adad
addasda | adad
asdsd | dad
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
asd | asdad
asd | adad
adsada | adad
addasda | adad
asdsd | dad

Related

Absolute wall positions in IFC

Because I want to associate windows with walls, I am trying to find the endpoints of a wall using IFCOpenShell.
#include <ifcgeom/IfcGeom.h>
#include <ifcparse/IfcFile.h>
using namespace Ifc2x3;
using namespace IfcSchema;
using namespace IfcParse;
using namespace IfcUtil;
using namespace IfcGeom;
std::string tostr(gp_XYZ a) {
std::stringstream ss;
ss << a.X() << "," << a.Y() << "," << a.Z();
return ss.str();
}
int main(int argc, char** argv) {
IfcFile file;
if (!file.Init(argc > 1 ? argv[1] : "windows connected to walls Archicad.ifc")) abort();
Kernel k;
gp_Pnt start;
gp_Pnt end;
auto list = file.entitiesByType<IfcWall>();
for ( auto it = list->begin(); it != list->end(); ++it) {
auto w1 = *it;
std::cout << "wall " << w1->entity->id() << std::endl;
bool suc = k.find_wall_end_points(w1, start, end);
std::cout << suc << std::endl;
std::cout << tostr(start.XYZ()) << std::endl;
std::cout << tostr(end.XYZ()) << std::endl;
}
}
This currently yields 10.1596,0,0 and 9.08038,0,0 as endpoints for two walls, and 0 as the starting point for both. This means they are parallel. But when I open the IFC file in Archicad, they are orthogonal. There is even an IFC tag in the file specifying that one wall connects to the other ATSTART/ATEND. How can I derive the correct coordinates?
Compilation command line: g++ -I/usr/include/oce wallpoints.cpp -l IfcGeom -l IfcParse $(for i in $(cd /usr/lib/x86_64-linux-gnu/; ls libTK*.so | cut -d. -f1 | cut -c4-); do echo "-l $i"; done) $(icu-config --ldflags) -ggdb3
IFC file: https://hushfile.it/592c22c69af2a#AwrpRI2O3ecDuAmP_pIjNmCAV3BWvwr30tfrazqJ
As stated in the standard, the placement is relative, so I have to multiply this with a couple of matrices.

Single Channel OpenCV Mat.at<> gives out wrong values

Declaring the Mat image, and assigning values.
Mat magnitude = Mat(gradient_columns.cols, gradient_columns.rows, CV_64FC1);
for(int i = 0; i < gradient_columns.cols; i++)
{
for(int j = 0; j < gradient_columns.rows; j++)
{
magnitude.at<double>(Point(i,j)) = (double)hypot(gradient_columns.at<double>(Point(i,j)), gradient_rows.at<double>(Point(i,j)));
}
}
Printing the above Mat:
cout << "M = " << magnitude << endl;
Result:
M = [0, 0, 0.1257399049164523, 12.36316814720732, 12.50461780753356, 0.2674320707434279, 10.39230484541326, 12.03299037437945, 5.430256687374658,
12.03299037437945, 4.684492386402418, 4.72934192083521, 12.16431633381293, 5.397674732957373, 12.30042244512288, 10.25834261322606, 0.3944487245360109,
12.16431633381293, 11.84297951775486, 12.44187210544911, 12.10132213098092,
0.4088817310696626, 10.15078660267586, 12.09573607646389, 2.076275433221507, 0, 0.1257399049164523, 0, 0.1257399049164523, 0;
.....
.....]
The above result is completely correct and as expected.
However if I try to print individual values I get wrong results:
cout.precision(20);
cout << "CHANNELS: " << magnitude.channels() << endl;
cout << magnitude.at<double>(Point(0, 2)) << endl;
cout << magnitude.at<double>(Point(0, 3)) << endl;
cout << magnitude.at<double>(Point(0, 4)) << endl;
cout << magnitude.at<double>(Point(0, 5)) << endl;
Result | Actual Value:
CHANNELS: 1
0.062870 | 0.1257399049164523,
0.000000 | 12.36316814720732,
0.031404 | 12.50461780753356,
0.000000 | 0.2674320707434279
I understand its some data type conversion issue, but if anyone can suggest any solution?
Thanks.
I believe that there is nothing wrong with your matrix. You are just not printing what you think you are.
When writing magnitude.at<double>(Point(0,2)), you're not printing the number in line 0 and column 2 as you expected, but the number in line 2 and column 0. Try to write magnitude.at<double>(0,2) instead.
For those who are having a similar issue and #Sunreef's answer does not work, check if you are accidentally using mat.at<float>(_,_) instead of mat.at<double>(_,_)

Locate the source of a bug with sscanf

I've been struggling with this for too long.
Let's say i have this minimal code:
test.cxx
#include <iostream>
#include <cstdio>
int main (int argc, char *argv[])
{
const char *text = "1.01 foo";
float value = 0;
char other[8];
int code = sscanf(text, "%f %7s", &value, other);
std::cout << code << " | " << text << " | => | " << value << " | " << other << " | " << std::endl;
return 0;
}
$ g++ test.cxx; ./a.out produces this output, as expected:
$ 2 | 1.01 foo | => | 1.01 | foo |
Now I have these 5 lines embedded into a project with several thousand lines, and lots of includes ...
Compiling, running, and the output is now:
$ 2 | 1.01 foo | => | 1 | .01 |
What strategy could I use to locate the source of this inconsistency ?
EDIT:
export LC_ALL=C (or LC_NUMERIC=C); ./a.out seems to solve my problem
It might be caused by a different locale in your test and in your destination application. I was able to reproduce it on coliru:
by using:
setlocale(LC_ALL, "cs_CZ.utf8");
http://coliru.stacked-crooked.com/a/5a8f2ea7ac330d66
You can find some solutions in this SO:
sscanf() and locales. How does one really parse things like "3.14"?
[edit]
Solution with uselocale, but since you tagged this question with C++ then why not use std::stringstream and imbue it with proper locale (see link to SO above).
http://coliru.stacked-crooked.com/a/dc0fac7d2533d95c
const char *text = "1.01 foo";
float value = 0;
char other[8];
// set for testing, sscanf will assume floating point numbers use comma instead of dots
setlocale(LC_ALL, "cs_CZ.utf8");
// Temporarily use C locale (uses dot in floats) on current thread
locale_t locale = newlocale(LC_NUMERIC_MASK, "C", NULL);
locale_t old_locale = uselocale(locale);
int code = sscanf(text, "%f %7s", &value, other);
std::cout << code << " | " << text << " | => | " << value << " | " << other << " | " << std::endl;
// Go back to original locale
uselocale(old_locale);
freelocale(locale);

char concat to string returns wrong length

simple c++ program that adds a char byte to a string. The resulting length is wrong in the output.
#include <iostream>
#include <string>
int main(){
char x = 0x01;
std::string test;
test = x+"test";
std::cout << "length: " << test.length() << std::endl;
std::cout << "test: " << test << std::endl;
return 0;
}
the output:
length: 3
test: est
I am prepending a type byte to the string because I am going to be sending this data through a socket and the other side has a factory that needs to know the type of object to create.
1 + "test" = "est" // 1 offset from test
So you are getting the correct answer.
+---+---+---+---+---+
| t | e | s | t | \0|
+---+---+---+---+---+
+0 +1 +2 +3 +4
What you want is possibly:
std::string test;
test += x;
test += "test";
You are not concatenating a char with a std::string as you think you are. This is because "test" is actually a literal const char*, so you are just doing pointer arithmetic when you add x to it. You can replace
test = x + "test";
with
test = std::to_string(x) + "test";
Then your output will be
length: 5
test: 1test

C++ Insertion << operator overload

How can I (in an external function) differentiate between cout << thingToShow and outfile << thingToWrite with different formats?
I have a single file that I am supposed to build all this implementation around without changing anything, and there are instances of
cout << "\nx matrix is: \n";
cout << x;
cout << "\ny matrix is: \n";
cout << y;
which are supposed to be formatted as
x matrix is:
--- ---
| 30 50 |
| |
| 25 40 |
--- ---
y matrix is:
--- ---
| 2 3 |
| |
| 1 1 |
--- ---
and I have instance of
w = r * w;
outfile << w;
which are supposed to be formatted simply as
-20 40
-80 60
my implementation is
ostream& operator<< (ostream &out, const Matrix& y){
out << "\t\t" << " ---\t\t\t\t ---\n"<< "\t\t|\t\t"<<y.tl<< "\t"<<y.tr<< "\t\t|\n\t\t|\t\t\t\t\t|\n\t\t|\t\t"<<y.bl<< "\t"<<y.br<< "\t\t|\n" << "\t\t" << " ---\t\t\t\t ---\n\n";
return out;
}
which works for the standard cout << thingToShow output format, but obviously messes up the outfile << thingToWrite format.
is there a property of the (stream &out,) argument I can put in an if statement? or is there some other way to differentiate between cout and outfile?
You can test if your ostream is cout:
if (&out == &std::cout)
And you can take the appropriate action, depending upon the result. But if you want my unsolicited opinion, I think it would be better to let the user decide how it prints out, using some kind of formatting class:
std::cout << format(my_matrix, fancy);
outfile << format(my_matrix, not_fancy);
In this example, format would be a function which returns an object of some class which holds a Matrix object (by reference), and formatting options. This class would have its operator<< overloaded to produce the appropriate output to the stream based on the options that were given to it. Alternatively, you could make your own specialized i/o manipulators.
Not quite as easy as I thought.
It can be done by overloading std::ifstream. That means you have to overload it for all types so a catch-all template overload is needed in addition to your Matrix overload.
struct Matrix
{
int a, b;
};
// Matrix for std::cout
std::ostream& operator<<(std::ostream& os, const Matrix& t)
{
os << "[\n\t" << t.a << "\n\t" << t.b << "\n]";
return os;
}
// overload of general types for files
template<typename Type>
std::ofstream& operator<<(std::ofstream& ofs, const Type& t)
{
// this cast prevents infinite recursion
static_cast<std::ostream&>(ofs) << t;
return ofs;
}
// Matrix overload for files
std::ofstream& operator<<(std::ofstream& ofs, const Matrix& t)
{
// this cast prevents infinite recursion
static_cast<std::ostream&>(ofs) << "{" << t.a << ", " << t.b << "}";
return ofs;
}
int main()
{
std::ofstream ofs("test.txt");
Matrix m {3, 7};
std::cout << 4 << m << 9 << '\n';
ofs << 4 << m << 9 << '\n';
}
Output: std::cout
4[
3
7
]9
Output: ofs
4{3, 7}9
NOTE: This approach distinguishes between std::ofstream and its parent class std::ostream. This means you have to pass your std::ifstream explicitly typed to any functions if you want this behaviour to be available within the function.
You need to maintain some short of state to decide whether the output is going to be in short format or the long format. The best place to maintain that data is, I think, in the class Matrix itself.
Then, provide functions that can be used to set the format. You can also provide an overloaded operator<< function so you can use them with an ostream.
Here's a working version.
#include <iostream>
struct Matrix
{
int tl;
int tr;
int bl;
int br;
static void setLongFormat();
static void setShortFormat();
enum OutputFormat
{
LONG_FROMAT,
SHORT_FORMAT
};
static OutputFormat outputFormat;
};
Matrix::OutputFormat Matrix::outputFormat = Matrix::SHORT_FORMAT;
void Matrix::setLongFormat()
{
outputFormat = LONG_FROMAT;
}
void Matrix::setShortFormat()
{
outputFormat = SHORT_FORMAT;
}
std::ostream& operator<< (std::ostream &out, const Matrix& y)
{
if ( Matrix::outputFormat == Matrix::LONG_FROMAT )
{
out << "\t\t" << " ---\t\t\t\t ---\n"
<< "\t\t|\t\t"<<y.tl<< "\t"<<y.tr<< "\t\t|\n"
<< "\t\t|\t\t\t\t\t|\n"
<< "\t\t|\t\t"<<y.bl<< "\t"<<y.br<< "\t\t|\n"
<< "\t\t" << " ---\t\t\t\t ---\n\n";
}
else
{
out << y.tl<< "\t" << y.tr<< "\n"
<< y.bl<< "\t" << y.br<< "\n";
}
return out;
}
std::ostream& operator<<(std::ostream &out, void (*fun)())
{
fun();
return out;
}
int main()
{
Matrix a{30, 50, 25, 40};
std::cout << Matrix::setLongFormat << a << std::endl;
std::cout << Matrix::setShortFormat << a << std::endl;
};
Output:
--- ---
| 30 50 |
| |
| 25 40 |
--- ---
30 50
25 40
PS. The tabs don't look quite right here. I am sure the function can be modified to keep the tabs in their correct location.