jshapy8
jshapy8

Reputation: 2051

"String Iterators Incompatible" error message when running bubble sort program

I am a beginner trying to bubble sort a vector of objects in C++. My goal is to sort the vector by member variables of each object element's member variable. So in the end, I would like the attributes off all the vector elements to be the same, just sorted in a different order. When I run the program, I get the following message:

enter image description here

Here is my code:

    void sortInventory(vector<Vehicle> &carList)
    {
    bool swap;      
    Vehicle temp;  

    do
    {
        swap = false;

        for (int count = 0; count < carList.size(); count++)
        {

            transform(carList[count].getVIN().begin(), carList[count].getVIN().end(), carList[count].getVIN().begin(), ::tolower);

            if (carList[count].getVIN() > carList[count + 1].getVIN())
            {
                temp = carList[count];                          
                carList[count] = carList[count + 1];
                carList[count + 1] = temp;
                swap = true;    
            }
        }

    } while (swap);
}

Here is my class declaration:

class Vehicle
{
private:
    string VIN;

public:
    string getVIN();
    void   setVIN(string);

};

Here is my class implementation:

string Vehicle::getVIN()
{   return VIN;     }

void Vehicle::setVIN(string input)
{   VIN = input;    }

By the way, I am aware that I am not using efficient methods, but I am just starting to learn the language and I am learning to write the code.

I asked a question similar to this here. However, none of the answers got me to where I wanted to go, although I feel like I am going in the right direction.

Upvotes: 0

Views: 538

Answers (2)

Jim Vargo
Jim Vargo

Reputation: 362

As jxh says, your transform line fails because you are making iterators to separate string objects. Why not try making the transform a separate routine? If you want to be fancy you can define it inside the sort routine as a lambda function. Or you can just make it a separate routine defined separately.

// returns a lower case version of the string
std::string lower_case(std::string VIN_number){

  auto begin = std::begin(VIN_number);
  auto end = std::end(VIN_number);

  // Your code acting on one fixed string
  std::transform(begin, end, begin, ::tolower);

  return VIN_number; 
 }

Then when you do your comparison, do something like

if ( lower_case(carList[count].getVIN()) > lower_case(carList[count + 1]).getVIN()) )

Upvotes: 1

jxh
jxh

Reputation: 70432

This line of code attempts to convert the string for the VIN into lowercase text, but fails:

        transform(carList[count].getVIN().begin(),
                  carList[count].getVIN().end(),
                  carList[count].getVIN().begin(),
                  ::tolower);

Each call to getVIN() results in a separate string instance. Since the iterators are not from the same string instance, the failure is the result.

You don't show how you populate your carList, but one possible way to fix this is to save the VIN in lowercase at the time you save the VIN in the carList.

Upvotes: 4

Related Questions