1

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.

user3529880
  • 11
  • 1
  • 1
  • 3
  • because when you enter a number it returns – user1231232141214124 Apr 13 '14 at 21:42
  • Re-read about do { ... } while. Return exits functions. To exit a loop like that, you probably want to break. – duncan Apr 13 '14 at 21:45
  • I suggest that you read about the **rubber ducking** technique described in the following blog post http://ericlippert.com/2014/03/05/how-to-debug-small-programs/ it will do you more good because you **will** need to use it again down the line. – nonsensickle Apr 13 '14 at 21:47
  • @nonsensickle, yes while thats important to learn, he REALLY needs to learn the absolute fundamentals first before even bothering to learn how to debug. There is zero reason to debug a program if you don't even know what the expected behavior is. – user1231232141214124 Apr 13 '14 at 21:48
  • `std::vector` has a `push_back` function. – chris Apr 13 '14 at 21:51
  • @redFIVE I agree. Rubber ducking is an attempt to force him to *go back to basics* and think about it. Hopefully, this will help him learn things that he is missing. – nonsensickle Apr 13 '14 at 22:05

4 Answers4

3

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;
}
101010
  • 41,839
  • 11
  • 94
  • 168
  • 1
    The `while (std::cin >> val)` line might not satisfy the *if zero is entered* condition. http://stackoverflow.com/questions/19307979/cin-in-a-while-loop `std::badbit` and `std::failbit` should both not be zero. – nonsensickle Apr 14 '14 at 00:50
  • @nonsensickle Indeed mate I'll add an update, thanks for remark. – 101010 Apr 14 '14 at 13:48
1

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.

user1231232141214124
  • 1,339
  • 3
  • 16
  • 22
1

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
nonsensickle
  • 4,438
  • 2
  • 34
  • 61
Ziker
  • 877
  • 2
  • 10
  • 30
  • You left out a pretty important ingredient; making sure we don't overflow the buffer. – M.M Apr 13 '14 at 22:54
  • @Ziker Your bullet point 1. doesn't make sense. You are trying to explain two things at the same time. Please split it up into two sentences explaining that arrays are zero indexed and that `i` cannot be left uninitialized. As it stands it makes no sense. – nonsensickle Apr 13 '14 at 23:59
  • @nonsensickle Fast thinking slow writing. (Hopefully) finally fixed – Ziker Apr 14 '14 at 00:09
  • Your answer is complemented by @redFIVE's answer very well. You explained the **how** while *redFIVE* explained the **why**. Both get +1. – nonsensickle Apr 14 '14 at 00:52
1

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.

nonsensickle
  • 4,438
  • 2
  • 34
  • 61