Reading in a variable number of integers with cin

Discussion in 'C++' started by H., Feb 6, 2006.

  1. H.

    H. Guest

    I'm writing a driver for something I wrote, and can't remember how to
    do this very simple thing. The code I have at this point in time:

    int myArr[100];
    int temp;
    int ind = 0;
    cout << "enter some integers: ";
    while (cin >> temp)
    {
    myArr[ind++] = temp;
    }

    The problem is that it doesn't exit until the user enters a non-number.
    It won't exit if the user simply hits enter.

    What I'm trying to create is something that allows the user to separate
    values by spaces, and press the Enter key when done entering them. A
    variable number of items will be separated by spaces, e.g.:
    "Enter the integers to be sorted with spaces between them and Enter to
    finish"
     
    H., Feb 6, 2006
    #1
    1. Advertisements

  2. H.

    int2str Guest

    The code you posted doesn't compile.
    Please make sure you post compilable code here if you want help.
    How do you know 100 is a good value? What if I want to enter 101
    numbers?
    Use a std::vector instead to keep your options open.
    Always initialize your variables.
    At index 101, this will blow ;)
    I'm probably doing your homework for you here, but I'll hope that the
    sorting algorithm is the real challenge here.

    Here's some code for you to work with:
    #include <iostream> // std::cout, std::endl
    #include <string> // std::string
    #include <sstream> // std::stringstream
    #include <vector> // std::vector
    #include <algorithm> // std::copy
    #include <iterator> // std::eek:stream_iterator

    int main()
    {
    std::cout << "Enter integers separated by spaces:\n";

    std::string line;
    if ( std::getline( std::cin, line ))
    {
    std::stringstream ss( line );
    std::vector<long> values;
    long l = 0;

    while( ss >> l )
    values.push_back( l );

    if ( values.size() )
    std::copy( values.begin(), values.end(),
    std::eek:stream_iterator<long>(std::cout, "\n"));
    }
    }

    Cheers,
    Andre
     
    int2str, Feb 6, 2006
    #2
    1. Advertisements

  3. H.

    H. Guest

    Thanks for all that, it was very educational. (Unfortunately, It's an
    overkill for what I'm trying to do, but again, thanks though.) Vectors
    are great; they can't be used for what I'm doing, arrays are needed.)
    And hard-coding the array number to 100 is fine for the testing driver
    I'm writing; there will never be 101 numbers. Basically the goal is to
    create something as simple as possible to get the job done, with no
    extra classes besides iostream. It is being used as a driver for a
    homework problem, but I already created a simpler driver that hard
    codes the number of entries, which is good enough for the assignment at
    hand, since the assignment is not about the numbers but manipulating
    them in a given way with recursion. Actually, for the driver, I could
    skip the user input altogether and just feed the recursive function all
    of the test lists, and so in that sense, it's not a homework problem at
    all, just a "for my edification" problem. I'll figure it out, because
    I'm sure it can't really be that hard a thing to do.



     
    H., Feb 6, 2006
    #3
  4. H.

    dragoncoder Guest

    I am not sure if I understand what you want but I think typing Ctrl-d
    on the unix terminal should end the while loop.

    Is that what you want?
     
    dragoncoder, Feb 6, 2006
    #4
  5. H.

    wittempj Guest

    If you want to keep the user input part you can do something like below
    #include <string>
    #include <sstream>
    #include <iostream>

    int main()
    {
    std::string inp;
    int temp(0);

    while (std::cin >> inp)
    {
    if ((inp == "q") ||(inp == "Q"))
    {
    break;
    }
    std::istringstream i(inp);
    if (!(i >> temp))
    {
    std::cerr << "Invalid item entered: " << inp << std::endl;
    }
    // add number here to your array
    }
    return 0;
    }
     
    wittempj, Feb 6, 2006
    #5
  6. H.

    Daniel T. Guest

    Then it must be a homework assignment.
    What 'int2str' provided was pretty simple. What do you have against
    using the tools the language provides?

    Your requirements were to enter a series of numbers separated by white
    space and ending with the return/enter key. The code he provided does
    exactly that. If you want a simpler solution, I suggest you pose a
    simpler problem.
     
    Daniel T., Feb 6, 2006
    #6
  7. : Here's some code for you to work with:
    : #include <iostream> // std::cout, std::endl
    : #include <string> // std::string
    : #include <sstream> // std::stringstream
    : #include <vector> // std::vector
    : #include <algorithm> // std::copy
    : #include <iterator> // std::eek:stream_iterator
    :
    : int main()
    : {
    : std::cout << "Enter integers separated by spaces:\n";
    :
    : std::string line;
    : if ( std::getline( std::cin, line ))
    : {
    : std::stringstream ss( line );

    Here:
    : std::vector<long> values;
    : long l = 0;
    :
    : while( ss >> l )
    : values.push_back( l );

    Since you already use ostream_iterator for output,
    how about using the single statement:
    std::vector<long> values
    ( std::istream_iterator<long>( ss )
    , std::istream_iterator<long>() );

    : if ( values.size() )
    : std::copy( values.begin(), values.end(),
    : std::eek:stream_iterator<long>(std::cout, "\n"));
    : }
    : }
    :
    : Cheers,
    : Andre

    .... only for the sake of consistency/completeness,
    Ivan
     
    Ivan Vecerina, Feb 6, 2006
    #7
  8. H.

    Daniel T. Guest

    void fn( vector<int>& myArr )
    {
    cout << "enter some integers: ";
    string line;
    if ( getline( cin, line ) )
    {
    myArr.clear();
    stringstream ss( line );
    copy( istream_iterator<long>( ss ), istream_iterator<long>(),
    back_inserter( myArr ) );
    }
    }

    Note, with the above: if the user enters a non-numeric char then the
    vector will be loaded up to that point but not after. If you want it to
    skip incorrect input, then I suggest going through the line first
    looking for non-digits...

    bool is_digit( char c ) {
    return isdigit( c );
    }

    // after "myArr.clear();"
    replace_if( line.begin(), line.end(),
    not1( ptr_fun( &is_digit ) ), ' ' );

    I have a question... I was unable to put isdigit directly into the
    ptr_fun (I had to wrap it.) Any help there?
     
    Daniel T., Feb 6, 2006
    #8
  9. H.

    Daniel T. Guest

    For that matter, copy will work:

    The above 'if' is unnecessary. Should values.begin() and values.end() be
    equal, copy will do the right thing.
     
    Daniel T., Feb 6, 2006
    #9
  10. H.

    int2str Guest

    No, it's not fine. Not even for testing.
    I don't believe you. Or to put it another way, there is no guarantee
    that there will "never" be 101 numbers.
    To look at your code snipper again:
    This simply contradicts you. With the while loop being what it is,
    there in fact CAN be 101 numbers. If you want to GUARANTEE that there
    will NEVER be 101 numbers, then have the code do the talking:

    while( cin >> temp && ind < 100 )
    ....

    And of course us a constant value instead of a magic number.

    Whenever you declare an array of fixed size, you need to make 100% sure
    that it cannot go out of bounds. Make it a habbit.

    Cheers,
    Andre
     
    int2str, Feb 6, 2006
    #10
  11. H.

    H. Guest

    Good point, thanks.
     
    H., Feb 6, 2006
    #11
  12. H.

    int2str Guest

    You know, especially if the assignment isn't about array handling
    itself, then you should go with a vector. You can access the elements
    in a vector just like in an array (ex. my_vect[1]). So the "meat" of
    your code (your recursive function) wouldn't look much different
    whether you used arrays or a vector.

    Cheers,
    Andre
     
    int2str, Feb 6, 2006
    #12
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.