Strange incrementing of iterators when passing them as an argument - c++

I immediately apologize for my terrible English :D
For my project, I need to analyze the obj file. I line-by-line read the file and select data from a specific string using regular expressions.
regex regCoord("-?\\d+\.?\\d*");
sregex_iterator a(line.begin(), line.end(), regCoord);
I know for sure that 3 matches have been found and I want to use them right away. For example, output to the console or save to a structure
cout << line << endl;
cout << a++->str() << " " << a++->str() << " " << a->str() << endl;
But in this case, incrementing occurs in the reverse order, from left to right! And on the output I get not (1st element, 2nd element, 3rd element), but (2nd element, 1st element, 1st element). A similar problem occurs if I pass all three elements to the structure constructor.
Output:
v 0.151164 0.014830 -0.051720
0.014830 0.151164 0.151164
But if I loop through the elements or write output in three lines, the result will look normal. Likewise, if I fill a structure without using a constructor, and write to each of its fields separately.
cout << a++->str() << " ";
cout << a++->str() << " ";
cout << a->str() << endl;
Output:
v 0.151164 0.014830 -0.051720
0.151164 0.014830 -0.051720
Why can there be such a strange inverted argument handling? I'm using Visual Studio 2017

Related

Why when I am using file.peek() in C++ do I get a number rather than the char?

In most of my code, the in.peek() works as getting whatever the next char is supposed to be. However, when it is reading some symbols, it returns a number rather than the char, and I am not sure how to fix it to get the symbol I want.
The text file reads:
print "Good morning!!";
but during the " char I use file.peek() to read the next symbol is a ; to change the state of my switch, but it comes out as a number instead of the symbol.
This is how I am trying to print, I even created a temp char and set it to in.peek(), but that just comes out as a blank space.
char temp = in.peek();
cout<<"hit " << ch << " "<< in.peek()<<" "<<temp << endl;
The output is: "hit " 10 "
With the last bit being a blank space. Does anyone know how I can fix this so I get the ;?
peek returns an int (to account for possibility of eof()). To make sure cout recognizes it as a char, you can cast it (though this will produce incorrect values if you did hit EOF), e.g.:
cout << "hit " << ch << " " << static_cast<char>(in.peek()) << " " << temp << endl;

can I Remove "endl" in ( cout<<" "<<endl ) in C++?

I am beginner at C++, my question is can I remove endl the one at the end of cout like :
cout<<" "<<endl;
I don't want return to new line . If I can't remove it, what should I do?
Elephant in the room: remove the endl from the cout.
But in case you don't own that code, you could try "\033[F", which, if your terminal supports it, moves you to the previous line.
Another possibility would be to redirect the cout buffer using rdbuf to an ostream that you control. You could (i) redirect, (ii) call the function that writes the errant cout with the new line and (iii) inspect your ostream and write to the original buffer, this time omitting the endl. Switch everything back once you're done.
Yes of course you do not need to use std::endl every time you use <<. As an example a simple way to print a vector with spaces between the elements would look like:
std::vector<int> foo = {1,2,3,4,5};
for (auto e : foo)
std::cout << e << " ";
Here we never use a endl. You cout also just use \n at the end of a string literal and that will put a newline in the buffer as well.
std::cout << "test\n";
std::cout << "this will be on a new line";
Notice that I don't put a newline in the last cout<< so if there is anymore output it will start off right after the "e" in "line".
Yes you can remove endl. It is an optional parameter to the << stream operator of which there are many. If you don't include it then a new Carriage Return/Line Feed character will not be output and therefore text will appear on the same line in the output (presumably console).
For example
cout << "Hello, World" << endl;
would become:
cout << "Hello, World";
or to make the point another way you could write:
cout << "Hello,";
cout << " World";
There are lots of other examples out there too, here's one for starters: http://www.cplusplus.com/doc/tutorial/basic_io/
cout<<"Your message here.";
It's as simple as that. Were you trying to do something like...
cout<<"Your message here."<<; ....? This is wrong as:
The << operator signifies that something comes after the "" part. You don't have any in this case.

Display a struct vector values based on 1 type

I'm currently trying to display the total no. of topicids and testids based on the name.
However I'm having trouble doing that display. I initially had a vector containing all the data.
For e.g.
user1:name:topic1:test1
user1:name:topic2:test1
user2:name:topic1:test1
user2:name:topic2:test1
Due to the multiple duplicates in the vector, I want to display in the following format:
username:name:numofTopics:numofTests
user1:name:2:2
user1:name:2:2
Therefore, i thought of comparing the name against the next name in the vector and push in the element to a new vector called singleAcc. The purpose of this is to display the duplicate element as ONE element.
Below is my code for displaying the data
vector<AccDetails> singleAcc;
for (vector<AccDetails>::iterator itr=accInfo.begin();itr!=accInfo.end()-1; ++itr) {
if (itr->name == itr[1].name) {
//cout << (*itr) << endl;
singleAcc.push_back(*itr);
}
}
for (vector<AccDetails>::iterator itr = singleAcc();itr!=singleAcc();++itr) {
cout << left
<< setfill(' ')
<< setw(20) << itr[0].username
<< setw(20) << itr[0].name
<< setw(20) << countTopics(itr->name)
<< setw(20) << countTests()
<< endl;
}
Problem:
On the first vector iteration, the name will not compare against the last element bcoz of accDetails.end()-1.
How to display the duplicate elements as ONE element? Is what I'm doing in the 2nd iteration the right thing?
Hope someone can help me with this. Or is there a better way to doing this?
Thanks!
Why this won't work
Your proposed solution simply won't work as intended. Consider three elements that are considered duplicates in consecutive subsequence (I am using numbers to simplify the concept):
[1,1,1]
The iterator will first compare 1 to 1, and then push_back the first one.
Then it will compare second 1 to the third one, which again returns true, and the result that was supposed to have no duplicates ends up:
[1,1]
So it's clearly not something you want to do. In general, it looks like a rather weird problem, but so solve this one part you've posted here, I suggest using std::multiset.
A better solution
Create a comparator that tests for the name field just like you do here.
Then, recovering unique fields is rather simple:
std::multiset<AccDetail> s;
for (auto element_it = s.begin(); element_it != s.end(); element_it = s.upper_bound(*element_it)) {
auto er = s.equal_range(*element_it);
// use this to get all the elements with given name
for (auto i = er.first; i != er.second; ++i)
cout << *i << " ";
// use this to get the number of them
cout << std::distance(er.first, er.second);
}
See a working sample on Coliru.
Bonus
You are right that the iterator in first loop would go over the bounds. The solution for that is rather simple: zip iterator which can handle this automatically.
for (auto elem_pair : zip(v, v | drop(1)))
if (elem_pair.first == elem_pair.second)
...
Boost.Range has tools that allow that code to work. It would still suffer from the problems I've mentioned, though.

Output of the cout changes according to typecasting way

I'm working on a program and have a strange, cout related problem. Since the program is a bit big and the code talks best, I'll paste the relevant snippets.
First, I have an iterator, *it defined in a for as
for(vector<facet*>::iterator it=facets_to_dump->begin(); it<facets_to_dump->end(); it++)
In this for, if I use the expression
facet* facet_to_work_on = *it;
cout << facet_to_work_on->facet_id << "\t";
Nicely prints out integers.
But, if I use the notation
cout << (facet*)(*it)->facet_id << "\t";
This code prints out hex values. Hex values are equal to the integer values. Any idea why this is happening?
Thanks in advance.
The reason
cout << (facet*)(*it)->facet_id << "\t";
prints out a hex value is that -> binds harder than the (facet*) cast, that is it evaluates
(*it)->facet_id
and casts the result to a facet*. Pointers are output in hex.
Try including <iomanip> and:
cout << dec << (facet*)(*it)->facet_id << "\t";
To say you want numbers in decimal form.

Aligning output to the terminal using C++

I am having a lot of trouble aligning my output to the terminal. I want to print a vector of vectors viz vector< vector<double> > myvec; to the output where myvec[i] occupies the ith row on the terminal. The vectors composing myvec have size 3
This is the way I am trying to print it.
for(unsigned int i=0; i<myvec.size() ; ++i )
{
cout<<myvec[i][0]<<" "
<<myvec[i][1]<<" "
<<myvec[i][2]<<'\n';
}
When I print this to output only the myvec[i][0] column of numbers is aligned properly. The rest of the numbers look messy. Is there a good way to align this output?
(Ignore the 0.7 printed to the right on line 5 of image)
You can use setw() to set the minimum number of characters you want to be written and left to output the data to the left. Like this:
cout << setw(8) << left << myvec[i][0];
This should fill the empty space with spaces but if not, then you can do:
cout << setw(8) << left << setfill(' ') << myvec[i][0];
You will need to #include <iomanip> for this.
Just a couple notes about your code:
Alignment types
quasiverse's answer gives you left justification, i.e. every number starts in the first character position. Drop the left to make it right-justify, i.e. every number starts in the last character position.
Aligning the decimal points is a bit harder. If you want to set a fixed number of digits past the decimal point, then replace the left with fixed and add setprecision(), giving it the number of digits you want past the decimal. For example, to show two digits past the decimal:
cout << setw(8) << fixed << setprecision(2) << myvec[i][0];
2-D Vectors
You're declaring vector< vector<double> > myvec;, but the minor (second) dimension appears hardcoded to 3. This means that you are creating a vector of vectors, where each row is an entire vector object with storage for three doubles.
vectors don't store their data internally; the actual vector object just stores the number of elements, a pointer to the actual data storage, and maybe a couple other things. The actual data is stored in a separate block. This will create a lot of overhead and memory fragmentation (every row allocates a block to store the data).
For example, for a 1000x3 vector, there is the top-level vector object on the stack, an array of 1000 vector objects (one per row) on the heap, and each of those points to a block of three doubles, so you have 1001 objects on the heap and every access has to go through two pointers. Slow and inefficient.
vector is overkill if the length is fixed. So I'd recommend having a vector of structures, with each structure having three doubles:
struct point {
double x, y, z;
};
vector<point> myvec;
This stores all the data in one block, since point is completely self-contained. Then your code is:
for(unsigned int i = 0; i < myvec.size() ; ++i)
{
cout << setw(8) << left << myvec[i].x << ' ' << setw(8) << left << myvec[i].y
<< ' ' << setw(8) << left << myvec[i].z << endl;
}
Or, the C++ iterator way to do it:
for(vector<point>::const_iterator elem = myvec.begin(); elem != myvec.end() ; ++elem)
{
cout << setw(8) << left << elem.x << ' ' << setw(8) << left << elem.y
<< ' ' << setw(8) << left << elem.z << endl;
}
This saves a bunch of calls to operator[]. If your compiler supports the new C++11 standard, you can change the for() line to:
for(auto elem = myvec.begin(); elem != myvec.end() ; ++elem)
where auto tells the compiler to make elem the same type as what myvec.begin() returns. Another C++11 way, less likely to be supported, is the range-based for loop:
for(auto elem: myvec)