Home > Software design >  Why can't I put an Object into the start of a vector C
Why can't I put an Object into the start of a vector C

Time:03-13

I'm writing a program in which I have to read complex numbers from the console into a vector, containing Complex objects. I have overwritten the >> operator in order to do this, but my vector gets indexed in the in the interval [1..vector.size()] instead of [0..vector.size()). I want it to go from zero, but I can't figure it out.

Here is a minimal reproducible example:

#include <iostream>
#include <vector>
#include <sstream>

using namespace std;

class Complex
{
    private:
        double real, im;
    public:
        Complex(double v_real = 0, double v_im = 0): real(v_real), im(v_im) {};
        // getters
        double getReal() const
        {
            return this->real;
        }
        double getImaginary() const
        {
            return this->im;
        }
        // setters
        void setReal(double v_real)
        {
            this->real = v_real;
        }
        void setImaginary(double v_im)
        {
            this->im = v_im;
        } 
};


void operator>>(istream& i, Complex& c)
{
    string line;
    getline(i,line);
    istringstream ss (line);

    double temp_real;
    double temp_im;
    char oper;
    ss >> temp_real;
    ss >> oper;
    ss >> temp_im;
    if (oper == '-') temp_im *= -1;
    char junk_i;
    ss >> junk_i;
    c.setReal(temp_real);
    c.setImaginary(temp_im);
}


ostream& operator<<(ostream& o, Complex c)
{
    if (c.getImaginary() > 0)
    {
        o<<c.getReal()<<' '<<c.getImaginary()<<'i'<<endl;
    }
    else
    {
        o<<c.getReal()<<c.getImaginary()<<'i'<<endl;
    }


    return o;
}


int main(){

    cout << "How many numbers will you create?" << endl;
    int num_of_complex; 
    cin >> num_of_complex;
    vector<Complex> v;
    Complex temp_c;

    for (int i = 0; i < num_of_complex; i  )
    {
        cin >> temp_c;
        v.push_back(temp_c);
    }

    for (int i = 0; i < v.size(); i  )
    {
        cout << v[i] << endl;
    }
}

Here is the input/output:

enter image description here

CodePudding user response:

The problem is that you're reading the first number with cin >> num_of_complex;, but this does not move the cursor to a new line! This means that the next call (i.e. the first call to your overridden >>) with getline will read only an empty line and try to convert nothing into a complex number.

You can fix this by ignoring everything in the input buffer until the next newline or to the end of the buffer after reading the first number. This is done with the method:

cin.ignore(numeric_limits<streamsize>::max(), '\n');

Full working example:

#include <iostream>
#include <vector>
#include <stream>
#include <limits>

using namespace std;

class Complex
{
private:
    double real, im;
public:
    Complex(double v_real = 0, double v_im = 0): real(v_real), im(v_im) {};

    // Getters.
    double getReal() const
    {
        return this->real;
    }
    double getImaginary() const
    {
        return this->im;
    }

    // Setters.
    void setReal(double v_real)
    {
        this->real = v_real;
    }
    void setImaginary(double v_im)
    {
        this->im = v_im;
    }
};


istream& operator>>(istream& i, Complex& c)
{
    string line;
    getline(i, line);
    istringstream ss (line);

    double temp_real;
    double temp_im;
    char oper;
    ss >> temp_real;
    ss >> oper;
    ss >> temp_im;
    if (oper == '-') temp_im *= -1;
    char junk_i;
    ss >> junk_i;
    c.setReal(temp_real);
    c.setImaginary(temp_im);

    return i;
}


ostream& operator<<(ostream& o, Complex c)
{
    if (c.getImaginary() > 0)
        o << c.getReal() << ' ' << c.getImaginary() << 'i' << endl;
    else
        o << c.getReal() << c.getImaginary() << 'i' << endl;

    return o;
}


int main()
{
    cout << "How many numbers will you create?" << endl;
    int num_of_complex;
    cin >> num_of_complex;

    // Ignore everything in the input buffer until a new line or the end
    // of the buffer.
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    vector<Complex> v;
    Complex temp_c;

    for (int i = 0; i < num_of_complex; i  )
    {
        cin >> temp_c;
        v.push_back(temp_c);
    }

    for (int i = 0; i < v.size(); i  )
    {
        cout << v[i] << endl;
    }
}

CodePudding user response:

but my vector gets indexed in the [1..vector.size()] interval instead of [0..vector.size()). I want it to go from zero, but I can't figure it out.

Subtract 1 from the 1 based index to get the 0 based index that is used by the standard vector. Example:

std::vector<int> v{5, 6, 7};
std::size_t index = 2; // should access value 6
std::cout << v[index - 1];
  • Related