Why doesn't std::cin choke on this?

Discussion in 'C++' started by William Payne, Jan 5, 2004.

  1. Hello, when I was writing a user-driven test program for a data structure I
    wrote, I encountered an annoying problem. The test program is laid out as a
    menu with several numbered options. The user selects one option by typing in
    its corresponding number (int). Depending on the choice he made, he may be
    asked to provide another integer (or no input at all). So all the user does
    is entering integers. I don't want the user to be able to cause problems or
    crashes by providing invalid input, but he is despite my error checking.
    Here follows output from my program here boiled down to a "minimum":
    $ ./test
    1 - choice one
    2 - choice two
    3 - exit program
    What is your choice? 1
    Enter integer to be doubled: 2+2
    2 doubled is 4
    1 - choice one
    2 - choice two
    3 - exit program
    What is your choice? Enter integer to be squared:

    In this test run the user presses 1 when asked for which choice he wants in
    the menu. But when asked to input an integer he enters 2+2, and cin does not
    go into an error state but leaves the last '2' plus a newline in the stream,
    triggering a new menu option (the '+' was eaten by a call to cin.get() which
    is supposed to get rid of the newline. Now how can I fix my code so it
    doesn't allow this? And why doesn't cin choke on 2+2 when asked to enter an
    integer?

    #include <iostream>
    #include <limits>
    #include <string>

    int enter_integer(const std::string& prompt);

    int main()
    {
    std::string prompt;

    while(true)
    {
    std::cout << "1 - choice one" << std::endl;
    std::cout << "2 - choice two" << std::endl;
    std::cout << "3 - exit program" << std::endl;

    int n = enter_integer("What is your choice? ");

    switch(n)
    {
    case 1:
    n = enter_integer("Enter integer to be doubled: ");

    std::cout << n << " doubled is " << n * 2 << std::endl;

    break;
    case 2:
    n = enter_integer("Enter integer to be squared: ");

    std::cout << n << " squared is " << n * n << std::endl;

    break;
    case 3:
    return 0;
    default:
    std::cout << n << " is an invalid menu choice." << std::endl;
    }
    }
    }

    int enter_integer(const std::string& prompt)
    {
    while(true)
    {
    std::cout << prompt << std::flush;

    int n;

    std::cin >> n;

    if(!std::cin)
    {
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(),
    '\n');

    std::cout << "You must enter an integer!" << std::endl;
    }
    else
    {
    std::cin.get(); /* Get rid of newline in the stream. */

    return n;
    }
    }

    return -1; /* Should never be reached. */
    }

    / William Payne
     
    William Payne, Jan 5, 2004
    #1
    1. Advertising

  2. William Payne wrote:
    >
    > Hello, when I was writing a user-driven test program for a data structure I
    > wrote, I encountered an annoying problem. The test program is laid out as a
    > menu with several numbered options. The user selects one option by typing in
    > its corresponding number (int).


    And this is your problem. You read an int.
    The simplest thing you can do is to forget the idea of reading an int.
    After all, if the user types 2, this is a character just like 'a' or 'b'.
    So read everything as character, it simpler then checking the stream for it's
    state, getting rid of the invalid input, clearing that error state and thus
    make the stream workable again.

    > Depending on the choice he made, he may be
    > asked to provide another integer (or no input at all).


    Having no input at all is tricky when you try to read an int. Again: If you
    read in a string, this becomes trivial.

    > So all the user does
    > is entering integers. I don't want the user to be able to cause problems or
    > crashes by providing invalid input, but he is despite my error checking.
    > Here follows output from my program here boiled down to a "minimum":
    > $ ./test
    > 1 - choice one
    > 2 - choice two
    > 3 - exit program
    > What is your choice? 1
    > Enter integer to be doubled: 2+2
    > 2 doubled is 4
    > 1 - choice one
    > 2 - choice two
    > 3 - exit program
    > What is your choice? Enter integer to be squared:
    >
    > In this test run the user presses 1 when asked for which choice he wants in
    > the menu. But when asked to input an integer he enters 2+2, and cin does not
    > go into an error state


    why should it?
    Streams are defined that they try to read as much as possible to fullfil the
    request. The request was to read an int, thus everything that can be an int
    is taken from the stream, in your case the first '2'. The rest is left in the
    input queue and is waiting for your program to read it.

    > but leaves the last '2' plus a newline in the stream,
    > triggering a new menu option (the '+' was eaten by a call to cin.get() which
    > is supposed to get rid of the newline. Now how can I fix my code so it
    > doesn't allow this?


    look up the ignore() function of the stream.
    But again, it's simpler to *not* read the users input as an int. Read it as a string,
    then try to extract the number from the string. This way the user can enter whetever
    he likes (even no 'numer' at all), and nothing special will happen: The users input
    is read as string and your number detection function will not be able to extract
    a number from that and thus your program will emit an error. But in no case the
    stream has entered a fail state and must be made useable again (for extracting
    something from a string, the stringstreams are a handy tool).

    > And why doesn't cin choke on 2+2 when asked to enter an
    > integer?


    See above. It's defined to be that way. If you had entered: '*2' it would
    have choked, because '*' is not a valid starting character for an integer.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Jan 5, 2004
    #2
    1. Advertising

  3. "William Payne" <> wrote...
    > Hello, when I was writing a user-driven test program for a data structure

    I
    > wrote, I encountered an annoying problem. The test program is laid out as

    a
    > menu with several numbered options. The user selects one option by typing

    in
    > its corresponding number (int). Depending on the choice he made, he may be
    > asked to provide another integer (or no input at all). So all the user

    does
    > is entering integers. I don't want the user to be able to cause problems

    or
    > crashes by providing invalid input, but he is despite my error checking.
    > Here follows output from my program here boiled down to a "minimum":
    > $ ./test
    > 1 - choice one
    > 2 - choice two


    Whoever designed this user interface should be shot. Why not write

    1 - to double an integer
    2 - to square an integer

    ?

    > 3 - exit program
    > What is your choice? 1
    > Enter integer to be doubled: 2+2
    > 2 doubled is 4
    > 1 - choice one
    > 2 - choice two
    > 3 - exit program
    > What is your choice? Enter integer to be squared:
    >
    > In this test run the user presses 1 when asked for which choice he wants

    in
    > the menu. But when asked to input an integer he enters 2+2, and cin does

    not
    > go into an error state but leaves the last '2' plus a newline in the

    stream,
    > triggering a new menu option (the '+' was eaten by a call to cin.get()

    which
    > is supposed to get rid of the newline. Now how can I fix my code so it
    > doesn't allow this? And why doesn't cin choke on 2+2 when asked to enter

    an
    > integer?


    Read the FAQ section 15. 15.2 and 15.3 apply, IMO.

    Victor
     
    Victor Bazarov, Jan 5, 2004
    #3
  4. Karl Heinz Buchegger wrote:
    >
    > William Payne wrote:
    > >
    > > Hello, when I was writing a user-driven test program for a data structure I
    > > wrote, I encountered an annoying problem. The test program is laid out as a
    > > menu with several numbered options. The user selects one option by typing in
    > > its corresponding number (int).

    >
    > And this is your problem. You read an int.
    > The simplest thing you can do is to forget the idea of reading an int.
    > After all, if the user types 2, this is a character just like 'a' or 'b'.
    > So read everything as character,


    Sorry, make that: as string. This also accounts for your user to enter 'abcdefg'
    in response to 'Enter a number'.

    > it simpler then checking the stream for it's
    > state, getting rid of the invalid input, clearing that error state and thus
    > make the stream workable again.
    >
    > > Depending on the choice he made, he may be
    > > asked to provide another integer (or no input at all).

    >
    > Having no input at all is tricky when you try to read an int. Again: If you
    > read in a string, this becomes trivial.
    >
    > > So all the user does
    > > is entering integers. I don't want the user to be able to cause problems or
    > > crashes by providing invalid input, but he is despite my error checking.
    > > Here follows output from my program here boiled down to a "minimum":
    > > $ ./test
    > > 1 - choice one
    > > 2 - choice two
    > > 3 - exit program
    > > What is your choice? 1
    > > Enter integer to be doubled: 2+2
    > > 2 doubled is 4
    > > 1 - choice one
    > > 2 - choice two
    > > 3 - exit program
    > > What is your choice? Enter integer to be squared:
    > >
    > > In this test run the user presses 1 when asked for which choice he wants in
    > > the menu. But when asked to input an integer he enters 2+2, and cin does not
    > > go into an error state

    >
    > why should it?
    > Streams are defined that they try to read as much as possible to fullfil the
    > request. The request was to read an int, thus everything that can be an int
    > is taken from the stream, in your case the first '2'. The rest is left in the
    > input queue and is waiting for your program to read it.
    >
    > > but leaves the last '2' plus a newline in the stream,
    > > triggering a new menu option (the '+' was eaten by a call to cin.get() which
    > > is supposed to get rid of the newline. Now how can I fix my code so it
    > > doesn't allow this?

    >
    > look up the ignore() function of the stream.
    > But again, it's simpler to *not* read the users input as an int. Read it as a string,
    > then try to extract the number from the string. This way the user can enter whetever
    > he likes (even no 'numer' at all), and nothing special will happen: The users input
    > is read as string and your number detection function will not be able to extract
    > a number from that and thus your program will emit an error. But in no case the
    > stream has entered a fail state and must be made useable again (for extracting
    > something from a string, the stringstreams are a handy tool).
    >
    > > And why doesn't cin choke on 2+2 when asked to enter an
    > > integer?

    >
    > See above. It's defined to be that way. If you had entered: '*2' it would
    > have choked, because '*' is not a valid starting character for an integer.
    >


    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Jan 5, 2004
    #4
  5. "Victor Bazarov" <> wrote in message
    news:DofKb.64288$I07.277140@attbi_s53...
    > "William Payne" <> wrote...


    [snip]

    > > 1 - choice one
    > > 2 - choice two

    >
    > Whoever designed this user interface should be shot. Why not write
    >
    > 1 - to double an integer
    > 2 - to square an integer
    >
    > ?


    [snip]

    LOL, I wrote that and I don't know what I was thinking. The real program has
    a menu laid out as you want, though.

    [snip]

    > Read the FAQ section 15. 15.2 and 15.3 apply, IMO.
    >
    > Victor
    >


    I read those sections as you suggested, and I have decided to store the
    initial input in a std::string rather than an int and perform error checking
    on the string (and converting to int if valid).

    Thanks for your reply.

    / William Payne
     
    William Payne, Jan 5, 2004
    #5
  6. "Karl Heinz Buchegger" <> wrote in message
    news:...
    > Karl Heinz Buchegger wrote:
    > >
    > > William Payne wrote:
    > > >
    > > > Hello, when I was writing a user-driven test program for a data

    structure I
    > > > wrote, I encountered an annoying problem. The test program is laid out

    as a
    > > > menu with several numbered options. The user selects one option by

    typing in
    > > > its corresponding number (int).

    > >
    > > And this is your problem. You read an int.
    > > The simplest thing you can do is to forget the idea of reading an int.
    > > After all, if the user types 2, this is a character just like 'a' or

    'b'.
    > > So read everything as character,

    >
    > Sorry, make that: as string. This also accounts for your user to enter

    'abcdefg'
    > in response to 'Enter a number'.
    >
    > > it simpler then checking the stream for it's
    > > state, getting rid of the invalid input, clearing that error state and

    thus
    > > make the stream workable again.
    > >
    > > > Depending on the choice he made, he may be
    > > > asked to provide another integer (or no input at all).

    > >
    > > Having no input at all is tricky when you try to read an int. Again: If

    you
    > > read in a string, this becomes trivial.
    > >
    > > > So all the user does
    > > > is entering integers. I don't want the user to be able to cause

    problems or
    > > > crashes by providing invalid input, but he is despite my error

    checking.
    > > > Here follows output from my program here boiled down to a "minimum":
    > > > $ ./test
    > > > 1 - choice one
    > > > 2 - choice two
    > > > 3 - exit program
    > > > What is your choice? 1
    > > > Enter integer to be doubled: 2+2
    > > > 2 doubled is 4
    > > > 1 - choice one
    > > > 2 - choice two
    > > > 3 - exit program
    > > > What is your choice? Enter integer to be squared:
    > > >
    > > > In this test run the user presses 1 when asked for which choice he

    wants in
    > > > the menu. But when asked to input an integer he enters 2+2, and cin

    does not
    > > > go into an error state

    > >
    > > why should it?
    > > Streams are defined that they try to read as much as possible to fullfil

    the
    > > request. The request was to read an int, thus everything that can be an

    int
    > > is taken from the stream, in your case the first '2'. The rest is left

    in the
    > > input queue and is waiting for your program to read it.
    > >
    > > > but leaves the last '2' plus a newline in the stream,
    > > > triggering a new menu option (the '+' was eaten by a call to cin.get()

    which
    > > > is supposed to get rid of the newline. Now how can I fix my code so it
    > > > doesn't allow this?

    > >
    > > look up the ignore() function of the stream.
    > > But again, it's simpler to *not* read the users input as an int. Read it

    as a string,
    > > then try to extract the number from the string. This way the user can

    enter whetever
    > > he likes (even no 'numer' at all), and nothing special will happen: The

    users input
    > > is read as string and your number detection function will not be able to

    extract
    > > a number from that and thus your program will emit an error. But in no

    case the
    > > stream has entered a fail state and must be made useable again (for

    extracting
    > > something from a string, the stringstreams are a handy tool).
    > >
    > > > And why doesn't cin choke on 2+2 when asked to enter an
    > > > integer?

    > >
    > > See above. It's defined to be that way. If you had entered: '*2' it

    would
    > > have choked, because '*' is not a valid starting character for an

    integer.
    > >

    >
    > --
    > Karl Heinz Buchegger
    >


    Thanks for your reply, Karl. I will do as you suggested and read the user
    input into a std::string.

    / William Payne
     
    William Payne, Jan 5, 2004
    #6
  7. "William Payne" <> wrote in message
    news:btc27v$ee9$...
    >
    > "Karl Heinz Buchegger" <> wrote in message
    > news:...
    > > Karl Heinz Buchegger wrote:
    > > >
    > > > William Payne wrote:
    > > > >
    > > > > Hello, when I was writing a user-driven test program for a data

    > structure I
    > > > > wrote, I encountered an annoying problem. The test program is laid

    out
    > as a
    > > > > menu with several numbered options. The user selects one option by

    > typing in
    > > > > its corresponding number (int).
    > > >
    > > > And this is your problem. You read an int.
    > > > The simplest thing you can do is to forget the idea of reading an int.
    > > > After all, if the user types 2, this is a character just like 'a' or

    > 'b'.
    > > > So read everything as character,

    > >
    > > Sorry, make that: as string. This also accounts for your user to enter

    > 'abcdefg'
    > > in response to 'Enter a number'.
    > >
    > > > it simpler then checking the stream for it's
    > > > state, getting rid of the invalid input, clearing that error state and

    > thus
    > > > make the stream workable again.
    > > >
    > > > > Depending on the choice he made, he may be
    > > > > asked to provide another integer (or no input at all).
    > > >
    > > > Having no input at all is tricky when you try to read an int. Again:

    If
    > you
    > > > read in a string, this becomes trivial.
    > > >
    > > > > So all the user does
    > > > > is entering integers. I don't want the user to be able to cause

    > problems or
    > > > > crashes by providing invalid input, but he is despite my error

    > checking.
    > > > > Here follows output from my program here boiled down to a "minimum":
    > > > > $ ./test
    > > > > 1 - choice one
    > > > > 2 - choice two
    > > > > 3 - exit program
    > > > > What is your choice? 1
    > > > > Enter integer to be doubled: 2+2
    > > > > 2 doubled is 4
    > > > > 1 - choice one
    > > > > 2 - choice two
    > > > > 3 - exit program
    > > > > What is your choice? Enter integer to be squared:
    > > > >
    > > > > In this test run the user presses 1 when asked for which choice he

    > wants in
    > > > > the menu. But when asked to input an integer he enters 2+2, and cin

    > does not
    > > > > go into an error state
    > > >
    > > > why should it?
    > > > Streams are defined that they try to read as much as possible to

    fullfil
    > the
    > > > request. The request was to read an int, thus everything that can be

    an
    > int
    > > > is taken from the stream, in your case the first '2'. The rest is left

    > in the
    > > > input queue and is waiting for your program to read it.
    > > >
    > > > > but leaves the last '2' plus a newline in the stream,
    > > > > triggering a new menu option (the '+' was eaten by a call to

    cin.get()
    > which
    > > > > is supposed to get rid of the newline. Now how can I fix my code so

    it
    > > > > doesn't allow this?
    > > >
    > > > look up the ignore() function of the stream.
    > > > But again, it's simpler to *not* read the users input as an int. Read

    it
    > as a string,
    > > > then try to extract the number from the string. This way the user can

    > enter whetever
    > > > he likes (even no 'numer' at all), and nothing special will happen:

    The
    > users input
    > > > is read as string and your number detection function will not be able

    to
    > extract
    > > > a number from that and thus your program will emit an error. But in no

    > case the
    > > > stream has entered a fail state and must be made useable again (for

    > extracting
    > > > something from a string, the stringstreams are a handy tool).
    > > >
    > > > > And why doesn't cin choke on 2+2 when asked to enter an
    > > > > integer?
    > > >
    > > > See above. It's defined to be that way. If you had entered: '*2' it

    > would
    > > > have choked, because '*' is not a valid starting character for an

    > integer.
    > > >

    > >
    > > --
    > > Karl Heinz Buchegger
    > >

    >
    > Thanks for your reply, Karl. I will do as you suggested and read the user
    > input into a std::string.
    >
    > / William Payne
    >
    >


    I have now written a small code snippet that prompts the user to enter an
    integer, a snippet which should reject any input that is not a valid
    integer. It seems to work but I would like to hear some comments on it if
    you please.

    int enter_integer(const std::string& prompt)
    {
    while(true)
    {
    std::cout << prompt << std::flush;

    int n;

    std::string input;

    /* Maybe use cin.getline() instead and complain if the user *
    * enters, for example, 2 2, instead of just silently dis- *
    * everything left in stream like we do now? */
    std::cin >> input;

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

    if(!check_if_valid_integer(input))
    {
    std::cout << input << " is not a valid integer." << std::endl;
    }
    else
    {
    std::stringstream ss;

    ss << input;

    /* check_if_valid_integer() doesn't catch cases where the user just
    *
    * enters '+' or '-', so we need this check here. Maybe we should
    *
    * check for that in check_if_valid_integer as well.
    */
    if((ss >> n))
    {
    return n;
    }
    else
    {
    std::cout << input << " is not a valid integer." << std::endl;
    }
    }
    }

    return -1; /* Should never be reached. Maybe throw exception? */
    }

    bool check_if_valid_integer(const std::string& s)
    {
    if(!isdigit(s[0]) && s[0] != '+' && s[0] != '-')
    {
    return false;
    }

    return count_if(s.begin() + 1, s.end(), isdigit) == 0;
    }

    Hope this post doesn't go unnoticed, since I decided to reply to this thread
    instead of starting a new one.

    / William Payne
     
    William Payne, Jan 5, 2004
    #7
  8. "William Payne" <> wrote in message
    news:btbuv0$dl4$...
    > Hello, when I was writing a user-driven test program for a data structure

    I
    > wrote, I encountered an annoying problem. The test program is laid out as

    a
    > menu with several numbered options. The user selects one option by typing

    in
    > its corresponding number (int). Depending on the choice he made, he may be
    > asked to provide another integer (or no input at all). So all the user

    does
    > is entering integers. I don't want the user to be able to cause problems

    or
    > crashes by providing invalid input, but he is despite my error checking.
    > Here follows output from my program here boiled down to a "minimum":
    > $ ./test
    > 1 - choice one
    > 2 - choice two
    > 3 - exit program
    > What is your choice? 1
    > Enter integer to be doubled: 2+2
    > 2 doubled is 4
    > 1 - choice one
    > 2 - choice two
    > 3 - exit program
    > What is your choice? Enter integer to be squared:
    >
    > In this test run the user presses 1 when asked for which choice he wants

    in
    > the menu. But when asked to input an integer he enters 2+2, and cin does

    not
    > go into an error state but leaves the last '2' plus a newline in the

    stream,
    > triggering a new menu option (the '+' was eaten by a call to cin.get()

    which
    > is supposed to get rid of the newline. Now how can I fix my code so it
    > doesn't allow this? And why doesn't cin choke on 2+2 when asked to enter

    an
    > integer?
    >


    Other replies have pointed out why it doesn't work but I think you will find
    that the right answer is not to use a string or at least
    not as in cin >> s.

    All programs of this type are line oriented and hence you need to read a
    line -
    1. use the function getline to read a whole line into a std::string.
    2. Make your line the basis of an istringstream, iss
    3. read your integer with if( iss >> i)
    4. skip whitespace with iss >> std::ws
    5. if iss.get() is not now EOF then there was some input you didn't ask for

    This does the biz without you explicitly parsing strings and also stops the
    user entering extra newlines (remember that all formatted input functions
    eat whitespace first and newlines are whitespace).
     
    Nick Hounsome, Jan 5, 2004
    #8
  9. "William Payne" <> wrote in message
    news:btceb8$kdr$...

    [Please snip out any text not relevant to your reply, thanks]

    | I have now written a small code snippet that prompts the user to enter an
    | integer, a snippet which should reject any input that is not a valid
    | integer. It seems to work but I would like to hear some comments on it if
    | you please.

    [snip]

    | Hope this post doesn't go unnoticed, since I decided to reply to this thread
    | instead of starting a new one.

    Oh, it was noticed alright :).

    Having said that, I have modified your code a little:

    bool check_if_valid_integer( const std::string& s )
    {
    static const char* ValidChars( "0123456789" );

    return s.find_first_not_of( ValidChars ) == std::string::npos;
    }

    int enter_integer( const std::string& prompt )
    {
    while( true )
    {
    std::cout << prompt << std::flush;

    int n;

    std::string input;
    std::getline( std::cin, input );

    if( !check_if_valid_integer( input ) )
    {
    std::cout << input << " is not a valid integer." << std::endl;
    return -1;
    // Note: '-1' is a valid integer, it is up to you if you
    // want to accept it - throwing an exception may be of
    // better here.
    }
    else
    {
    std::istringstream ss( input );

    if( ss >> n )
    return n;
    }
    }
    }

    Cheers.
    Chris Val
     
    Chris \( Val \), Jan 6, 2004
    #9
  10. William Payne

    Duane Hebert Guest

    <snip>
    > bool check_if_valid_integer( const std::string& s )
    > {
    > static const char* ValidChars( "0123456789" );
    >
    > return s.find_first_not_of( ValidChars ) == std::string::npos;
    > }


    wouldn't this be better named check_if_valid_unsigned_integer() ?
    To check for valid integer, you need to allow '-' but only in the first postion
    no? Why not just use strstream functions?
     
    Duane Hebert, Jan 6, 2004
    #10
  11. "Duane Hebert" <> wrote in message
    news:pbrKb.74404$...
    | <snip>
    | > bool check_if_valid_integer( const std::string& s )
    | > {
    | > static const char* ValidChars( "0123456789" );
    | >
    | > return s.find_first_not_of( ValidChars ) == std::string::npos;
    | > }
    |
    | wouldn't this be better named check_if_valid_unsigned_integer() ?
    | To check for valid integer, you need to allow '-' but only in the first postion
    | no? Why not just use strstream functions?

    Your right(but I didn't want to change it), that's why
    I mentioned it, but still allowed it to return a negative
    value for the error code.

    I should have been a little more clear :).

    Cheers.
    Chris Val
     
    Chris \( Val \), Jan 6, 2004
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. TaiwanNoWhere

    cin and cin.clear() problem

    TaiwanNoWhere, Oct 13, 2003, in forum: C++
    Replies:
    8
    Views:
    4,109
    P.J. Plauger
    Oct 17, 2003
  2. Chris Mantoulidis

    std::cin.ignore() and std::cin.clear()

    Chris Mantoulidis, Jan 6, 2004, in forum: C++
    Replies:
    5
    Views:
    17,177
    Kevin Saff
    Jan 6, 2004
  3. Aleander

    cin and cin.getline()

    Aleander, Mar 6, 2005, in forum: C++
    Replies:
    5
    Views:
    8,704
    Alex Vinokur
    Mar 6, 2005
  4. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,995
    Smokey Grindel
    Dec 2, 2006
  5. puzzlecracker
    Replies:
    3
    Views:
    1,777
    Mike Wahler
    May 8, 2006
Loading...

Share This Page