Hello World!

Hello everyone! I have a little bit of a problem, It shouldn't be a problem for anyone. On that note, this post is basically just to say hi to everyone! I decided to join this community, because its always nice to have people who can annoy people who can answer my newbie questions.

I didn't think it was right to put a post just saying hi, So I will be including a problem!

When i write this little snippet of code

1
2
3
4
5
6
7
8
9
10
11
12
13
...
int iSomething;
for(;;)
{
   cin >> iSomething;
   if(iSomething == 0)
   {
   cout << "Zeros are ignored, Input a Positive number" <<endl;
   continue;
   }
...
...
}}


When i have this in my program, i realize one thing. If a user inputs any charaters (Or a number outside the limits of int), then iSomething seems to get overloaded, and gets stuck with a value of 0, creating an endless loop.

I thought of a way to get out of the constant loop that occurs, by calling a function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
bool ExitCheck ()
{
   static int nExitCount = 0;
   nExitCount++;
   if(nExitCount == 100)
   {
   return true; //tells the program to Exit and return 1
   }
   else
   {
   return false; //Tells the for loop to continue
   }
}
...
...
...

int iSomething;
bool Exit;
for(;;)
{
   cin >> iSomething;
   if(iSomething == 0)
   {
      cout << "Zeros are ignored, Input a Positive number" <<endl;
      Exit = ExitCheck();
      if(!Exit)
      {
      continue;
      }
      else
      {
      return 1;
      }
   }
...
...
}}

This would prevent the program from terminating if the user actually inputted the number zero(unless they did it a hundred times) Yet it would shut the program down if the the loop was causing a zero over and over again.

My question is (finally) how would i go about making my exit code obsolete? If some one enters a character for my nSomething, i would want to be able to erase that value, and allow them to give it another attempt.

I was looking around at the other posts, just to take a peek at other peoples programming, and i saw the mentioning of a "cin.ignore()" and i am wondering if that's where the answer lies

Well, i would like some feedback. I don't care if its just to say "Hello, welcome to the community" or if it's to say "Your programming style sucks!" or if its the answer to my question! Like i said, im just posting this to say hi to the community.

So to Sum up my post in a couple of words:

Hello World! ^_^
Last edited on
> i saw the mentioning of a "cin.ignore()" and i am wondering if that's where the answer lies

Yes. In conjunction with std::cin.clear() ;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

int read_int( int min, int max )
{
    int value ;
    std::cout << "enter an integer in the range [" << min << '-' << max << "]: " ;
    if( std::cin >> value && value >= min && value <= max ) return value ;
    else
    {
        std::cout << "error in input.\n" ; // inform the user
        std::cin.clear() ; // clear the error
        std::cin.ignore( 1024, '\n' ) ; // throw away the junk (upto 1024 characters)
        return read_int( min, max ) ; // and try again
    }
}
Though it is better done without recursion.

Andy

1
2
3
4
5
6
7
8
9
10
11
12
13
int read_int( int min, int max )
{
    for( ; ; ) // loop forever
    {
        std::cout << "enter an integer in the range [" << min << '-' << max << "]: " ;
        int value = 0;
        if( std::cin >> value && value >= min && value <= max )
            return value ;
        std::cout << "error in input.\n" ; // inform the user
        std::cin.clear() ; // clear the error
        std::cin.ignore( 1024, '\n' ) ; // throw away the junk (up to 1024 characters)
    }
}


Last edited on
> Though it is better done without recursion.

You need to educate yourself on recursion.
Given the two solutions are next to identical, except for the loop versus recursive call, I would go for the iterative solution as it avoids the unnecessary, extra stack pushing and popping.

I follow the school of thought that believes that recursion should only be used when the degree of simplification justifies the call overhead (however small it is.)

Andy
Last edited on
> Given the two solutions are next to identical, except for the loop versus recursive call,
> I would go for the iterative solution as it avoids the unnecessary, extra stack pushing and popping.
> ... recursion should only be used when the degree of simplification justifies the call overhead

Repeat: You need to educate yourself on recursion.

Tip: the simpler the function involving the tail call, the easier it is for the optimizer to perform TCO.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
int cstr_to_int_iterative( const char* digits )
{
    int number = 0 ;
    for( int i = 0 ; digits[i] != 0 ; ++i )
        number = number * 10 + digits[i] - '0' ;
    return number ;

    /*
    // GCC 4.8 i686 with -O3 -fomit-frame-pointer

    __Z21cstr_to_int_iterativePKc:
    LFB0:
        movl	4(%esp), %ecx
        movsbl	(%ecx), %edx
        testb	%dl, %dl
        je	L4
        addl	$1, %ecx
        xorl	%eax, %eax
    L3:
        addl	$1, %ecx
        leal	(%eax,%eax,4), %eax
        leal	-48(%edx,%eax,2), %eax
        movsbl	-1(%ecx), %edx
        testb	%dl, %dl
        jne	L3
        rep ret
    L4:
        xorl	%eax, %eax
        ret
    */
}

int cstr_to_int_recursive( const char* digits, int number = 0 )
{
   if( digits[0] == 0 ) return number ;
   return cstr_to_int_recursive( digits+1, number*10 + digits[0] - '0' ) ;

    /*
    // GCC 4.8 i686 with -O3 -fomit-frame-pointer

    __Z21cstr_to_int_recursivePKci:
    LFB1:
        movl	4(%esp), %ecx
        movl	8(%esp), %eax
        movsbl	(%ecx), %edx
        testb	%dl, %dl
        je	L10
    L11:
        addl	$1, %ecx
        leal	(%eax,%eax,4), %eax
        leal	-48(%edx,%eax,2), %eax
        movsbl	(%ecx), %edx
        testb	%dl, %dl
        jne	L11
    L10:
        rep ret
    */
}
I am aware of tail recursion.

To clarify: are you saying that your original iterative function, read_int(), will also be tail-call optimized?

Andy
Last edited on
Thank you for answering my newbie question! =D

lulz, I love nerd battles, but jeez guys:

This is all I was looking for:

1
2
std::cin.clear() ; // clear the error
std::cin.ignore( 1024, '\n' ) ; // throw away the junk (upto 1024 characters) 


Another question I had about std::cin.ignore()
I figured out if I put cin.ignore() directly on top of an input line:

1
2
std::cin.ignore(2, '\n')
std::cin >> iSomething


When I press enter with 10-99 (2 charcters), nothing happens, so it gets ignored, just creates a new line on the command prompt.

What if I wanted to instruct the program to ignore ANYTHING over 9
so in human terms:
Tell the following "std::cin >>iSomething" to ignore the input if the user inputs anything larger then 1 character


you could just do something like
1
2
3
4
5
6
int input;
while( !std::cin >> input || input > 9 )
{
    std::cin.clear();
    std::cin.ignore( 1024 , '\n' ); //You can also use numeric_limits.
}


Edit..pretty much this function says while you cannot input a number or it is greater than 9 you clear the input stream and then ignore everything then get a new input and check if it is greater than 9. If it is not greater than 9 then you move on keeping that number.


EDIT:: looks like jl and andre already answered this earlier chillie =p

EDIT:::if you use numeric_limits its like this
1
2
#include <climits>
std::numeric_limits<std::streamsize>::max(); //for stream max anyways which you would use for ingore 
Last edited on
> "std::cin >>iSomething" to ignore the input if the user inputs anything larger then 1 character

1
2
3
4
5
6
7
8
9
char c ; std::cin >> c ; // read one non-whitespace character

std::string str ;

// read upto a maximum of five characters after skipping leading white space
std::cin >> std::setw(5) >> str ;

// throw away everything after that upto and including a new line
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' ) ;



> are you saying that your original iterative function, read_int(), will also be tail-call optimized?

When I mentioned TCO, I was responding to: "recursion should only be used when the degree of simplification justifies the call overhead (however small it is.)"

Re: avoiding "the unnecessary, extra stack pushing and popping" in this particular function? At the end of an iteration in which there were more than half a dozen calls to non-trivial library functions? Which involved blocking to read and parse an integer typed in by the user?

I find that concern laughable.
Lol, giblet your right, they did already answer the question in the aspects of creating a separate rule dealing with numbers, but I was more then less referring to what JL stated

1
2
// read upto a maximum of five characters after skipping leading white space
std::cin >> std::setw(5) >> str ;

This will allow me to block out anything more then 1 character (whether it be 0-9 or a-z)


As for this:
1
2
std::numeric_limits<std::streamsize>::max(); 
//for stream max anyways which you would use for ingore 

I really like this aswell because I get errors if the user enters a number higher then int's limits. So now I should be able avoid that

Thank you everyone =]
closed account (NyhkoG1T)
i encountered this issue the other day, where I inputted a letter and an infinite loop occured. This is how I fixed it.

1
2
3
4
5
6
			if(!cin) {
				cout << endl << "You entered an ERRONEOUS value. Please try again." << endl;
				cin.clear();
				cin.ignore();
				continue; //test code is inside infinite loop
			}


Whenever you enter something the isn't correct, like a letter for an integer value, cin set's a failbit. You can check that failbit by using either if(!cin) or if(cin.fail())

The above code worked flawlessly but if anyone knows of any reason not to use this, please enlighten me.
Try putting in a number greater than 9. look at the code I posted. It checks if it fails or if the number is greater than 9 if so then it repeats.
Very good Lucian, but giblet already gave that answer with this snippit

1
2
3
4
5
while( !cin >>input || input > 9 )
{
    cin.clear();
    cin.ignore( 1024 , '\n' );
}


My new, current question:

What do I have to #include to grant myself the use of

1
2
int iSomething;
cin>>setw(1)>>iSomething;


My apologies if this is unnecessary, I know I could just use
1
2
3
int iSomething;
cin>>iSomething;
if(iSomething > 9) {}


Just realized this is completely not what I am trying to accomplish. because if some one typed in "12" then it would read as "1" instead of ignoring the "12" altogether.

Still, I would like to know what I need to #include to gain access to setw() when im dealing with strings


I like to teach my self ALL the ways to skin a cat
Last edited on
#include <iomanip>
http://www.cplusplus.com/reference/iomanip/

Also my method shouldn't read in 12 because 12 is greater than 9 and I meant || not && earlier because we want it to get a new number if it is less than 9 or it is a letter( fails to input. ) and not get a new number only if both of those are true.
Thank you giblet, You have been very helpful ^_^ I completely understand what your saying.

That will be the end to my questions for today
Topic archived. No new replies allowed.