Error while simultaneously accessing members of two lists? - c++

I am facing some unknown errors while iterating through two lists simultaneously in c++ (visual studio). Two lists are of the same length.
I am following the procedure, mentioned in (link). Unable to figure out where am I making mistake. Could anybody help me resolve this error
Function with for loop
int Two_Lists_ForLoop(std::initializer_list<dmat> list1, std::initializer_list<string> list2)
{
std::list<dmat>::iterator it1 = list1.begin();
std::list<string>::iterator it2 = list2.begin();
for (; it1 != list1.end() && it2 != list2.end(); ++it1, ++it2){
//run some code
cout << *it1 << endl;
cout << *it2 << endl;
}
return 0;
}
Function with while loop
int Two_Lists_WhileLoop(std::initializer_list<dvec> list1, std::initializer_list<string> list2)
{
std::list<dvec>::iterator it1 = list1.begin();
std::list<string>::iterator it2 = list2.begin();
while (it1 != list1.end() && it2 != list2.end()) {
//run some code
cout << *it1 << endl;
cout << *it2 << endl;
it1++;
it2++;
}
return 0;
}
I've included list.h headerfile. The errors I am getting are as follows (I do not know, how to resolve these errors)
Thanks in advance.

Related

How to use the member type iterator of std::list with a while loop to make simple changes to a list

I create and modify a simple list. I replace the element at index 1 of the list. How would I semantically accomplish the same thing with a while loop. The tutorial instructor remarked that the current code is quite ugly and a while loop would accomplish the same thing in a much more simple and pretty fashion. I can't figure it out.
#include <iostream>
#include <list>
int main() {
std::list<int> numbers;
numbers.push_back(1);
numbers.push_back(2);
numbers.push_back(3);
numbers.push_front(0);
std::list<int>::iterator it = numbers.begin();
it++;
numbers.insert(it, 100);
std::cout << "Current element is: " << *it << '\n';
std::list<int>::iterator eraseIt = numbers.begin();
eraseIt++;
eraseIt = numbers.erase(eraseIt);
std::cout << "erasing at element: " << *eraseIt << '\n';
for (std::list<int>::iterator it = numbers.begin(); it != numbers.end();) {
if (*it == 2) {
numbers.insert(it, 1234);
}
if (*it == 1) {
it = numbers.erase(it);
} else {
it++;
}
}
for (std::list<int>::iterator it = numbers.begin(); it != numbers.end();
it++) {
std::cout << *it << '\n';
}
return 0;
}
You can probably do this if iterators are required:
// ...
std::list<int>::iterator it = ++numbers.begin();
numbers.insert(it, 100);
std::cout << "Current element is: " << *it << '\n';
std::list<int>::iterator eraseIt = ++numbers.begin();
eraseIt = numbers.erase(eraseIt);
std::cout << "erasing at element: " << *eraseIt << '\n';
it = numbers.begin();
while (it != numbers.end())
{
if (*it == 2) {
numbers.insert(it, 1234);
}
if (*it == 1) {
it = numbers.erase(it);
}
else {
++it;
}
}
for (auto& i : numbers)
{
std::cout << i << std::endl;
}
// ...

How to repeat and print 2 or more for loops?

I am trying to print out values from my txt file. I created a struct so that I can easily search for the element in the txt file. So for my first for loop I searched for "CC" as the first option and then I print. It works. However when I try copy the same loop and search for something else, lets say "SN" so that I can print all the values with SN as the first option, the second and subsequent loop does not print. It only works if I copy the long code again and create a new function but I do not want to do that because I try to keep it compact.
cout << "\nCC Students:" << endl;
int cc = 0;
for (; it != v.end(); it++)
{
if ((*it).First == "CC"){
cout << (*it).Name << " " << (*it).GPA << "\n";
if (++cc == 10)
break;
}
} // can print
cout << "\nSN Students:" << endl;
int sn = 0;
for (; it != v.end(); it++)
{
if ((*it).First == "SN"){
cout << (*it).Name << " " << (*it).GPA << "\n";
if (++sn == 10)
break;
}
} // cannot print
The question doesn't show the initialization of it, but from the context it seems to be an iterator on v. The first loop exhausts the iterator, and terminates when it reaches v.end(). When you start another loop, you should reinitialize it to v.begin(), e.g.:
for (it = v.begin(); it != v.end(); it++)
// Here ^

C++ Iterator access next element for comparison

I'm trying to compare two elements in a List by 'peeking' into the next element in the list. Using C++11.
Is this possible? I'm having some trouble.
#include <list>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
list<int> intList;
intList.push_back(10);
intList.push_back(20);
intList.push_back(30);
intList.push_back(30);
list<int>::iterator it;
for (it = intList.begin(); it != intList.end(); it++)
{
if (*it == *it + 1)
cout << "Duplicate: " << *it << '\n';
}
}
Yes, it's possible:
assert(!intList.empty()); // else ++begin is UB
for (list<int>::iterator it1 = intList.begin(), it2 = ++intList.begin();
it2 != intList.end(); ++it1, ++it2)
{
if (*it1 == *it2)
cout << "Duplicate: " << *it1 << '\n';
}
Your search can be simplified by using std::adjacent_find() instead (which supports std::list iterators):
Searches the range [first, last) for two consecutive identical elements.
For example:
list<int>::iterator it = std::adjacent_find(intList.begin(), intList.end());
if (it != intList.end())
cout << "Duplicate: " << *it << '\n';`
It's possible but your confronting *it with *it augmented by 1 (that is even different).
I suppose your intention was to confront two adiacent element of the list, so [thanks to DeiDei for the correction]
if ( false == intList.empty() )
{
auto it { intList.cbegin() };
auto oldVal { *it };
for ( ; ++it != intList.cend() ; oldVal = *it )
{
if ( *it == oldVal )
cout << "Duplicate: " << oldVal << '\n';
}
}
p.s.: sorry for my bad English

Delete an element from a list C++

I have a problem, I'm trying to delete an element in a string list but it doesn't work for the last position. I would also like to display the position of the iterator with an arithmetic operation.
list l = {"a","b","c", "d"};
for(std::list<string>::iterator it = l.begin(); it != l.end(); it++)
cout << " &l["<< it - l.begin() <<"]: " << &*it << " l["<< it - l.begin() <<"]: " << *it << endl;
cout << endl;
for(std::list<string>::iterator itt = l.begin(); itt != l.end(); itt++){
if(*itt == "d") itt = l.erase(itt);
cout << " &l["<< itt - l.begin() <<"]: " << &*itt << " l["<< itt - l.begin() <<"]: " << *itt << endl;
}
Thank you for your help.
It "doesn't work" because this line will cause itt to become the end() iterator when erasing the last element:
if(*itt == "d") itt = l.erase(itt);
Then the for loop does itt++ before the loop condition check, and incrementing the end() iterator is undefined behavior.
You need to modify your loop like this:
for (std::list<string>::iterator itt = l.begin(); itt != l.end(); /* */) {
if (*itt == "d") {
itt = l.erase(itt);
} else {
++itt;
}
// You cannot safely access *itt here because it might be l.end()
}
Two issues. First:
it - l.begin()
List iterators aren't random access, so they don't have operator-() defined for the obvious reason that that would be an expensive operation. If you want to do that, you have to do:
std::distance(l.begin(), it);
Second, the line:
itt = l.erase(itt);
for the last element will cause itt to become l.end(), so the subsequent itt++ is undefined behavior. What you will have to do instead is conditionally increment the iterator:
for (std::list<string>::iterator itt = l.begin(); itt != l.end(); /* nothing */) {
if (*itt == "d") {
itt = l.erase(itt);
}
else {
// cout stuff here
++itt;
}
}

forloop, iterators and vectors doesn't cooperate with me

Why does this work fine for me:
for(int i = 0; i < vec.size(); i++)
{
os << vec[i] << " ";
}
while this doesn't:
for(vector<int>::iterator it = vec.begin(); it < vec.end(); it++)
{
os << vec[*it] << " ";
}
You should be printing *it instead of using it as the index and you should probably change the condition to it != vec.end().
You're using the iterator wrong, it should be:
for(vector<int>::iterator it = vec.begin(); it < vec.end(); it++)
{
os << *it << " ";
}
Your code just attempts to print the element at index *it, which might not even be valid.