user3529880
user3529880

Reputation: 11

Taking in array of unknown size in c++

Ok I am extremely new to programming, and I am taking a c++ class. Basically for the current project I have to take in an array of unknown size, resize it, and output a bunch of statistics like average, Q1, Q3, etc. I am having trouble taking in the array from the user. I need to quit taking in variables once they enter 0. Here is what I have:

int i = 1; //When I first posted this I didn't mean to comment out the '= 1' part
do {
    cin >> array[i];
    if (array[i] != 0)
        return true;
} while (true);

What am I doing wrong? the program stops after I enter 1 number every time no matter what number I enter.

I am using vector class btw.

Upvotes: 1

Views: 17320

Answers (4)

Dimitrios Bouzas
Dimitrios Bouzas

Reputation: 42889

Do the following:

// change int to your type
int val;
std::vector<int> vec; 
while(std::cin >> val) {
  if(val == 0) break;
  vec.push_back(val);
}

Reason: Stating a return clause causes to exit the loop.

use of std::vector ensures the arbitrary size condition.

Update after @nonsensickle's constructive remark:

The following piece of code also ensures the only 0 terminates input process condition:

// change int to your type
int val;
std::vector<int> vec; 
do {
  if(std::cin >> val) {
    if(val == 0) break;
    vec.push_back(val);
  } else { // fix broken input stream in case of bad input
    std::cin.clear();
    std::cin.ignore(1,'\n');
  }
} while(true);

and a more sophisticated way, although overkill but what the hell :), with templates and type traits:

template <typename T> 
struct zero_traits
{
  static T getzero() { return T(0); }
};

template <>
struct zero_traits<std::string> 
{
  static std::string getzero() { return "0"; }
};

template <>
struct zero_traits<char> 
{
  static char getzero() { return '0'; }
};

template <typename T>
std::vector<T> read_values()
{
  T val;
  std::vector<T> vec; 
  do {
    if(std::cin >> val) {
      if(val == zero_traits<T>::getzero()) break;
      vec.push_back(val);
    } else {
      std::cin.clear();
      std::cin.ignore(1,'\n');
    }
  } while(true);
  return vec;
}

int main()
{
// change int to your type
std::vector<int> vec = read_values<int>();
for(auto i : vec) std::cout << i << std::endl;
}

Upvotes: 3

Ziker
Ziker

Reputation: 906

Before answering your question.

  1. Initialize your variables int i=0; .You assign i to be zero because arrays are zero indexed.
  2. You have to incerement i. If do not increment it, i will point at the first "bucket" in your array the whole time. Use i++ or i = i + 1 after every iteration of the do while loop to move "forward" in your array.
  3. You want your program to run until zero is entered so you have to write your condition like this if (array[i] == 0) return true;. This condition is true when the last number entered was zero and it will cause your method to return. It would be more elegant for you to check for it in the while clause.

Putting it all together, your code should look like this

int i=0;
do {
    cin >> array[i];
    if (array[i] != 0) break;
    i++;
} while (i < maxSize);
//do stuff with filled array

Upvotes: 1

nonsensickle
nonsensickle

Reputation: 4528

I will not try to answer your question directly. What you have is a small logic error and a misunderstanding of the do {...} while () looping construct. What you need is to learn how to step through your code.

Let's go through your code line by line (there are only 6 lines here so it should be really easy):

  1. int i; - Ok, so we are declaring an integer i here but are not giving it a value. As such, i can have a random value.
  2. do { - This is where we will come back to when we evaluate the while clause. But only if the result of the while clause is true.
  3. cin >> array[i] - Store a value that the user enters in the array at the position i. Here we ask ourselves a question, what is i? We should know its value without having to run the program. Hint: there's a problem here because of i
  4. if (array[i] != 0) - If the number entered by the user is not zero return true (exit this function with the result true).
  5. } while (true); - Go back to the do { line and redo all the steps until you get here. There is no condition here so it will keep happening until we exit this function.

Hint: The only exit point of your loop is at step 4.

With this, you should be able to figure out your problem. Trying to break down the problem for yourself should be your first step.

I recommend reading this blog post on debugging small programs. It should be informative.

Though code posted by others (in particular @DimitriosBouzas) will work, and is the better choice, I strongly recommend fixing your code and learning why it failed. This will help you in the long run more than @DimitriosBouzas' elegant solution.

Upvotes: 1

user1231232141214124
user1231232141214124

Reputation: 1349

First of all i will never increment.

Second of all, if (array[i] != 0) will return if that array's value doesn't equal 0.

You need to read into how do { ... } while() loops work as well as what return statements do. Might as well throw in how to increment an array while you're at it.

Upvotes: 1

Related Questions