Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

For loops and user input

  1. Feb 21, 2016 #1
    I'm wanting to take user input and store it into an array.There is a a minimum and maximum number of input but otherwise the user should be able to enter any number of integers in between. Say the max number is 10 but I only want to enter 5 numbers. I used a for loop but it only ends if the maximum number is entered. Is there a way to make it end after the user has entered the desired number of integers? Or should I use a different method? (Also I'm not sure how the code editor works)

    Code (C):

    const int MAXSIZE = 10;
    int Input[MAXSIZE];

    for (int i = 0; i<MAXSIZE ; i++)
        {
            cout << "Enter a positive integer: ";
            cin >> Input[i];

            if (Input[i]< 0) // terminate loop if negative number is entered
                break;
        }
    }
     
     
    Last edited by a moderator: Feb 21, 2016
  2. jcsd
  3. Feb 21, 2016 #2

    phinds

    User Avatar
    Gold Member
    2016 Award

    Why not have the user first enter the number of elements he wants to input and use THAT as the loop count? OR, have the user enter some particular value that flags no more entries, something like -9999
     
  4. Feb 21, 2016 #3

    QuantumQuest

    User Avatar
    Gold Member

    I think that the best is what phinds suggests, otherwise you'll need some if construct inside your for loop like:
    Code (C):

    if (i < MAXSIZE/2) {
       // take user input
    }
    It is also a very good idea to combine some needed things into your loop conditional like:
    Code (C):

    while ( i < MAXSIZE && userInput != -9999) {
        // do whatever you need here
    }
     
    Last edited: Feb 21, 2016
  5. Feb 21, 2016 #4

    Mark44

    Staff: Mentor

    The OP is doing something like this, except that instead of a specific sentinel value like -9999, he is terminating the loop on any negative integer. In the loop, the user is prompted to enter a positive integer, but the prompt should also include a message that a negative value terminates input.
     
  6. Feb 21, 2016 #5

    phinds

    User Avatar
    Gold Member
    2016 Award

    Thanks. I just glanced at the code but was focusing on the question so overlooked the obvious.
     
  7. Feb 21, 2016 #6

    QuantumQuest

    User Avatar
    Gold Member

    Actually, OP is doing this but he has to include a message prompting user for negative values terminating the loop. If on some other case, negative values are permitted input, he has to specify something like -1 or -9999 (a matter of usual practice).
     
    Last edited: Feb 21, 2016
  8. Feb 21, 2016 #7

    Mark44

    Staff: Mentor

    That's pretty much what I said.
    The prompt should indicate that either a) any negative number terminates the loop, or b) a specific negative number terminates the loop. Since the existing prompt asks for positive numbers, the user should be able to enter 0 to terminate the loop.

    As long as the program provides some information to the user how to terminate early, it works for me. In a user interface, you have to make some assumptions about the ability of the person using the program.
     
  9. Feb 21, 2016 #8

    QuantumQuest

    User Avatar
    Gold Member

    Yes, I was already editing my post.
     
  10. Feb 21, 2016 #9

    jtbell

    User Avatar

    Staff: Mentor

    Instead of using a fixed-size array and having to prevent the user from "walking past the end", you should seriously consider using a vector instead. A C++ vector works a lot like an array, but with extra features. For example, it can grow automatically to accommodate the input, and it can tell you how big it is at any time.

    Code (C):

    #include <iostream>
    #include <vector>

    using namespace std;

    int main ()
    {
      vector<int> Input;  // initially size is 0
      while (true)
      {
          cout << "Enter a positive integer: ";
          int num;
          cin >> num;
          if (num < 0)
              break;
          else
              Input.push_back(num);  // append num to Input and increase the
                                     // size of Input as needed
      }

      // the size() member function tells you how big the vector is

      cout "You entrered:" << endl;
      for (int k = 0; k < Input.size(); ++k)
      {
          cout << Input[k] << endl;
      }

      return 0;
    }
     
     
  11. Feb 22, 2016 #10

    Svein

    User Avatar
    Science Advisor

    Sigh. Both the OP and the answer assumes that the input from the user is reasonable. What if the user inputs the string "four"? What if the input is empty?

    It reminds me - back in the nineties I was employed at Tandberg Data. One of the things we produced was keyboards, containing a small microcontroller. The guy who did the development had his code working and proudly announced that to his group leader. In order to test his code, she turned the keyboard upside down and sat on it - the keyboard promptly stopped working. No - it was not finished, since it was not "idiot proof".
     
  12. Feb 22, 2016 #11

    jtbell

    User Avatar

    Staff: Mentor

    First one learns to crawl, then to walk, then to run; then how to train for a marathon, then for the Ironman... :oldwink:
     
  13. Feb 22, 2016 #12

    Mark44

    Staff: Mentor

    I agree. In the context of this problem, it seems reasonable to me to assume some level of intelligence on the part of the program user. IOW, if the user is prompted to enter a positive integer, it can be assumed that he/she won't type in "four" or the like. For a commercial program, OTOH, it's reasonable to assume that some users will be idiots, and to write the program accordingly.
     
  14. Feb 23, 2016 #13
    Thanks for the responses. I tried implementing some of your suggestions. Since I'm just a beginner programmer I having trouble with this other part of the program where I want to sort the array of numbers. I think I'm on the right track using pointers but the way I've got it set up it only prints the address of the first element however many integers the user inputs. Really I'm just trying to understand pointers and why it keeps outputing the same address. Also I am trying to get the hang of pass by reference. If one of the function parameters is a pointer can I pass the array of user inputs into it and then print that array sorted? This code is a mess but I am trying to learn how everything is working and why this doesn't work.

    Code (C):
    void sort(int *x, int j)
    {

        for (int i = 0; i < j-1; i++)
        {
            //const int j = 5;
            int num[j];
            int *pnum;
            pnum = num;
            int k = i;
            while (i > i + 1)
            {
                if (num[k - 1] > num[k])
                {
                    num[k] = num[k - 1];
                               // I feel like there needs to be an increment or decrement operator here
                             }
                   cout << num <<endl; // prints out the same address j-1 times
                   }
             }
    }
     
  15. Feb 23, 2016 #14
    I'm sorry that I am doing something wrong with the code editor. How am I suppose to use it properly?
    Edit: I figured it out.
     
  16. Feb 23, 2016 #15

    Mark44

    Staff: Mentor

    You can't declare num as you did; i.e., as int num[j]; To declare an array, its size must be known at compile time. Passing j as a parameter means that the size of the array isn't known until run time.
    Your sort function has a parameter x, which is a pointer, but there is no further mention of x in your code. The name of an array is a kind of pointer (a constant pointer). You could use your parameter x in place of the local array num.

    In your last line what you are doing is printing num (an address) each iteration of the loop. Again, the name of an array evaluates to the address of the first element of the loop. num[k] evaluates to the element at index k.

    Edit: I just noticed this: while (i > i + 1)
    This is never true -- a number can't be larger than 1 more than that number, so the loop body will not execute at all. The output statement you have won't execute for this reason. And besides, your sort() function shouldn't be doing output except possibly for help in debugging it, with the output statements removed once it's working.

    There are a number of things wrong with your code. Once you get something working, we can look at some more of the problems.
     
    Last edited: Feb 23, 2016
  17. Feb 23, 2016 #16

    jtbell

    User Avatar

    Staff: Mentor

    Here's another advantage to using vectors, in addition to the one I gave in my previous post. You can declare a vector with an initial size that is not known until run time:

    Code (C):

    vector<int> num(j);
     
    If you omit the initial size, it defaults to zero as in my previous example.

    Note you use parentheses rather than square brackets. This is because the size is actually the argument of a special function called the "constructor."
     
  18. Feb 23, 2016 #17

    rcgldr

    User Avatar
    Homework Helper

    ISO C99 compliant compilers allow variable length arrays (VLA), C++ standards changed support for VLAs back to optional (depends on compiler). Microsoft C / C++ compilers don't support it (and never did), but _alloca() could be used for the equivalent:

    Code (Text):

    int * num = _alloca(j * sizeof(int));
     
    http://en.wikipedia.org/wiki/Variable-length_array

    Take a look at the wiki example for bubble sort.

    http://en.wikipedia.org/wiki/Bubble_sort#Pseudocode_implementation

    Note that swap in C is usually done using a temp variable:

    Code (Text):

        tmp = A[i-1];
        A[i-1] = A[i];
        A[i] = tmp;
     
     
  19. Feb 23, 2016 #18

    jtbell

    User Avatar

    Staff: Mentor

    C++ didn't have variable-length arrays until the C++14 standard. (I'm still not even up to speed with C++11! :eek:) It looks like there are two flavors: runtime-sized arrays which are like C's VLAs; and std::dynarray which is a templated standard library container class like std::vector, std::list, etc.

    http://blog.smartbear.com/development/a-glimpse-into-c14/
     
  20. Feb 23, 2016 #19

    rcgldr

    User Avatar
    Homework Helper

    GCC may have always had it as an option for C++ (I've never used GCC, but I see referenced a lot). Microsoft C, including Visual Studio versions up to 2015, is C89 or C90, not C99, so it never supported VLAs. Although Visual Studio C++ compilers are more up to date, for example lambda expressions / function were added with VS2010, VLAs continued to not be supported. VS2010 is the last version that can run on Win XP and/or Win XP X64.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook