1

So I'm trying to let the user supply the elements of two vectors but using a while (cin >> ..) would crash my program. Here is what I have so far:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    size_t size = 4; int i;
    vector<int> product;

    vector<int> v1;
    vector<int> v2;

    int input, input2;

    cout << "Enter values for first vector: ";
    while (cin >> input) {
        v1.push_back(input);
    }
    cout << "Enter values for second vector: ";
    while (cin >> input2) {
        v2.push_back(input2);
    }

    int result = 0;
    if (size >= 1) {
        result += v1[0]*v2[0];
        for (int i = 1; i < size; ++i)
            result -= v1[i]*v2[i];
    }

    cout << result << endl;

    return 0;
}

User has to input N elements for the first vector and another N elements for the second vector. However, I cannot skip the usage of reading till EOF because I don't know how many elements the users want to store in each vector.

schmitsz
  • 175
  • 1
  • 13

3 Answers3

3

Your program is crashing because it's incorrectly assuming that the vectors are non-empty.

Imagine that first vector has three elements and the user enters zero elements for the second. Nothing prevents your code from executing result += v1[0]*v2[0];, which accesses the first element of v2.

So before anything else you should fix your check for empty vectors.


However, I cannot skip the usage of reading till EOF

I don't think it's guaranteed by the standard, and it may depend on the platform, but funnily enough I believe you actually can sometimes read from stdin until EOF, and then reopen or clear the input error, and then continue reading more input until (a second) EOF. I wouldn't recommend it though.

There are better solutions. You can ask the user to input each vector on its own line, so you know they're done entering elements for one vector once you reach the end of the line, or you can ask the user to tell you how many elements they're going to enter, and then read just that many elements.

I'm sure you can implement the latter suggestion on your own. Here's a simple implementation of the former.

#include <sstream> // for istringstream
#include <string>  // for string and getline()
#include <vector>

int main() {
  vector<int> v;

  string line;
  if (getline(cin, line)) {
    istringstream is(line);
    int i;
    while (is >> i) {
      v.push_back(i);
    }
  }

}

Basically, we read a line from the user's input, and then we create another stream from just that one line, and handle reading ints from that stream just like you handled reading them directly from the user's input.

bames53
  • 86,085
  • 15
  • 179
  • 244
1

Don't you want the user to enter the number of elements to be entered?

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    size_t size; int i;
    vector<int> product;

    vector<int> v1;
    vector<int> v2;

    int input, input2;

    cout << "Enter vector size: ";
    cin >> size;

    cout << "Enter values for first vector: " << endl;
    i = 0;
    while (i++ != size) {
        cin >> input;
        v1.push_back(input);
    }   
    cout << "Enter values for second vector: " << endl;
    i = 0;
    while (i++ != size) {
        cin >> input2;
        v2.push_back(input2);
    }

    int result = 0;
    if (size >= 1) {
        result += v1[0] * v2[0];
        for (int i = 1; i < size; ++i)
            result -= v1[i] * v2[i];
    }

    cout << result << endl;

    system("pause");
    return 0;
}
dspfnder
  • 1,135
  • 1
  • 8
  • 13
  • What happens with this code if the user enters a negative size? Or if they enter 'asdf' instead of a number? Always validate all user inputs. – bames53 Jan 21 '15 at 23:28
  • And don't use `system("pause");` To see the output when running the program on Windows 1) run without debugging (ctrl-f5) if using visual studio 2) if you want to run with debugging, put a breakpoint after the output and before program exit, or 3) follow [these](http://stackoverflow.com/questions/11881938/right-click-open-with-arguments) instructions to create an Explorer right click command named "Open in cmd.exe window" using a command of `cmd.exe /k "%1" %*`. – bames53 Jan 21 '15 at 23:34
  • The point of the code was to indicate what was missing. Not to create a crash-proof program. – dspfnder Jan 21 '15 at 23:36
  • Okay, I think it would have been better to describe it in words then; You can be more specific about exactly what changes to the code are relevant and what about them is relevant. Furthermore, sample code that appears to work will likely be assumed to be fully working and correct. – bames53 Jan 21 '15 at 23:43
0

You need to clear the error state and any bad data from cin before you load the second vector.

std::vector<int> loadValues() {
  std::vector<int> v;
  int input;
  while (std::cin >> input)
    v.push_back(input);

  std::cin.clear();
  std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
  return v;
}

Then, as others have pointed out, you need to check the size of the two vectors before you use them.

Live demo

Chris Drew
  • 14,926
  • 3
  • 34
  • 54