Thread: Sentinel Value and numbering

  1. #1
    Registered User fjf314's Avatar
    Join Date
    Jan 2004
    Posts
    13

    Sentinel Value and numbering

    Right now, I'm trying to write a program that simply lets the user enter in numbers, which are then stored in a file. My problem stems from the fact that this is my first instance in using a sentinel value to allow the user to enter in information as long as they wish. I just need to number the user's inputs on the screen, but I can't seem to figure out how, since the program doesn't actually use a loop to enter in my more values. Here is my code thus far:

    Code:
    #include<iostream.h>
    #include<iomanip.h>
    #include<fstream.h>
    
    const int SENTINEL = 1337;
    
    
    int main()
    {
    
    	int data;
    	int number;
    	ofstream out_file;
    
    	cout << "This program is designed to record up to 50 scores between the values of 0 and";
    	cout << " 100.  The scores will then be stored in another file.  Please enter all of";
    	cout << " the needed scores and type -1337 to end the program and store the values.";
    	cout << endl << endl;
    
    	number = 1;
    
    	out_file.open("stat_data");
    	cout << "Enter an integer (1337 to end input):\n";
    	cout << number << ".  ";
    	cin >> data;
    
    
    	while ( data < 1 || data > 1000)
    	{
    				
    		cout << "\nThe number entered was not within the parameters. \n\nPlease try again:\n";
    		cin >> data;
    			
    	}
    
    	while (data != SENTINEL)
    	{
    		out_file << data << " ";
    		cout << "Enter an integer (1337 to end input): ";
    		cin >> data;
    	}
    
    	out_file.close();
    return 0;
    }
    The variable "number" is what I'm using to label each input. When I had loops in the past, I could just insert

    Code:
    number = number++;
    but not now. Thanks for any help.
    Last edited by fjf314; 01-08-2004 at 07:04 PM.
    Programming With: Microsoft Visual C++ 6.0

  2. #2
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    You are allowed to nest loops. For example:
    Code:
    while (data is not sentinel)
    {
        ask for user input into data
        while (data is valid or is sentinel)
        {
            warn about invalid data
            ask for user input into data
        }
    }
    You of course have to figure out how to use this idea in your code to avoid problems like outputting the sentinel or not initializing the data correctly.

  3. #3
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    You also never test the status of the stream. If the user enters an 'a' rather than a number then you have a very long wait ahead of you.

    Code:
    std::vector<int> nums;
    int n;
    while(std::cin >> n && n != 1337) {
        if(n >= 1 && n <= 100) {
            std::cout << n << "is valid, added to list" << std::endl;
            nums.push_back(n);
        } else {
            std::cout << n << "is not valid, rejected" << std::endl;
        }
    }    
    for(int i = 0; i < nums.size(); ++i) {
        std::cout << (i+1) << " : " << nums[i] << '\n';
    }
    std::cout << std::flush();

  4. #4
    Registered User fjf314's Avatar
    Join Date
    Jan 2004
    Posts
    13
    Thanks for the help, but that doesn't seem to work. I tried creating the while statement with the other statements nested, but the output was still messed up, and it only displays the number I need the first time. For example, after my program description is displayed I get:

    Enter an integer (1337 to end input):
    1. user input
    Enter an integer (1337 to end input): user input
    Enter an integer (1337 to end input): user input

    And so on. The program is only outputting the variable number once, when I need it every line. Yet I can't figure out what I'm doing. This is my code after the while statement:

    Code:
    int main()
    {
    
    	int data;
    	int number;
    	ofstream out_file;
    
    	cout << "This program is designed to record up to 50 scores between the values of 0 and";
    	cout << " 100.  The scores will then be stored in another file.  Please enter all of";
    	cout << " the needed scores and type -1337 to end the program and store the values.";
    	cout << endl << endl;
    
    	number = 1;
    		
    	out_file.open("stat_data");
    	
    	while (data != SENTINEL)
    	{
    		number = number++;
    		cout << "Enter an integer (1337 to end input):\n";
    		cout << number << ".  ";
    		cin >> data;
    
    		while (data < 1 || data > 1000)
    		{
    					
    			cout << "\nThe number entered was not within the parameters. \n\nPlease try again:\n";
    			cin >> data;
    			
    		}
    	
    
    		while (data != SENTINEL)
    		{
    			out_file << data << " ";
    			cout << "Enter an integer (1337 to end input): ";
    			cin >> data;
    		}
    	}
    
    	out_file.close();
    	return 0;
    }

    Grib, I know I didn't do that, but it's not required for this program. I've only had one semester of C++, and my teacher isn't concerned with that yet, since we haven't gone over anything like it. Just getting the basic program done is her only real concern right now. Thanks for noting it, though.
    Last edited by fjf314; 01-08-2004 at 08:28 PM.
    Programming With: Microsoft Visual C++ 6.0

  5. #5
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Look at your code again, and step through it in your head (or even better in a debugger, but your head will do fine). You will see why this is happening.

  6. #6
    Registered User fjf314's Avatar
    Join Date
    Jan 2004
    Posts
    13
    The problem is I keep doing just that, but I keep thinking it should work. I don't know what the problem is. I've gotten a few of my friends to check it out, too, but they can't find anything wrong with it, either.
    Programming With: Microsoft Visual C++ 6.0

  7. #7
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    #1) change your sentinal to something logical, like -1. Make it a #define and every place you use or display the sentinal, use the #define (including your instructions)
    #2) Add print statements at key places in your code to see what section you are in at any given time.
    #3) Concentrate on your 2nd nested while to see if it's doing what you want
    #4) Shorten (or split) your print statement in your first nested while so it's not all on 1 line. There's no need to create a line that long.
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  8. #8
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Let's see if I can help you through it (hopefully you are looking at the same code you posted last).
    Code:
    int main()
    {
    
    	int data;
    	int number;
    	ofstream out_file;
    
    	cout << "This program is designed to record up to 50 scores between the values of 0 and";
    	cout << " 100.  The scores will then be stored in another file.  Please enter all of";
    	cout << " the needed scores and type -1337 to end the program and store the values.";
    	cout << endl << endl;
    
    	number = 1;
    		
    	out_file.open("stat_data");
    Set everything up, output description and two blank lines, open a file called "stat_data" in the current directory for writing.

    Output:
    This program is designed to record up to 50 scores between the values of 0 and 100. The scores will then be stored in another file. Please enter all of the needed scores and type -1337 to end the program and store the values.
    Code:
    	while (data != SENTINEL)
    Does data equal SENTINEL? Well, data was not initialized yet, so it could be anything. This is not your problem, but you should initialize data to some number other than the SENTINEL just in case. For now, we'll assume you are lucky and data does not equal SENTINEL, so we enter this loop.
    Code:
    	{
    		number = number++;
    number is incremented. Of course, number wasn't initialized either, so I assume you are getting lucky and your compiler is initializing to 0 for you. You shouldn't count on that and instead you should initialize the ints to something at the beginning (like 0).
    Code:
    		cout << "Enter an integer (1337 to end input):\n";
    		cout << number << ".  ";
    Output an instruction, the value of number, and a period.

    Output:
    This program is designed to record up to 50 scores between the values of 0 and 100. The scores will then be stored in another file. Please enter all of the needed scores and type -1337 to end the program and store the values.

    Enter an integer (1337 to end input):
    1.
    Code:
    		cin >> data;
    Wait for user input. Assume you are the user and you type 87 and Enter. Then data is filled with the number 87.

    Output:
    This program is designed to record up to 50 scores between the values of 0 and 100. The scores will then be stored in another file. Please enter all of the needed scores and type -1337 to end the program and store the values.

    Enter an integer (1337 to end input):
    1. 87
    Code:
    		while (data < 1 || data > 1000)
    Since data is 87, it is not less than 1 or greater than 1000, so the expression is false. The block of code will not be executed at all.
    Code:
    		{
    					
    			cout << "\nThe number entered was not within the parameters. \n\nPlease try again:\n";
    			cin >> data;
    			
    		}
    This is not executed because the while above evaluated to false.
    Code:
    		while (data != SENTINEL)
    Since 87 does not equal SENTINEL (1337), this expression evaluates to true, so the code inside this while loop is executed.
    Code:
    		{
    			out_file << data << " ";
    output the data (87) to the file.
    Code:
    			cout << "Enter an integer (1337 to end input): ";
    Request more data from the user.

    Output:
    This program is designed to record up to 50 scores between the values of 0 and 100. The scores will then be stored in another file. Please enter all of the needed scores and type -1337 to end the program and store the values.

    Enter an integer (1337 to end input):
    1. 87
    Enter an integer (1337 to end input):
    Code:
    			cin >> data;
    Wait for user input. Assume you are the user and you type 90 and Enter. Then data is filled with the number 90.

    Output:
    This program is designed to record up to 50 scores between the values of 0 and 100. The scores will then be stored in another file. Please enter all of the needed scores and type -1337 to end the program and store the values.

    Enter an integer (1337 to end input):
    1. 87
    Enter an integer (1337 to end input): 90
    Code:
    		}
    Continue back up to the top of the while loop.
    Code:
    		while (data != SENTINEL)
    Since 90 does not equal SENTINEL (1337), this expression evaluates to true, so the code inside this while loop is executed.
    Code:
    		{
    			out_file << data << " ";
    output the data (90) to the file.
    Code:
    			cout << "Enter an integer (1337 to end input): ";
    Request more data from the user.

    Output:
    This program is designed to record up to 50 scores between the values of 0 and 100. The scores will then be stored in another file. Please enter all of the needed scores and type -1337 to end the program and store the values.

    Enter an integer (1337 to end input):
    1. 87
    Enter an integer (1337 to end input): 90
    Enter an integer (1337 to end input):
    Code:
    			cin >> data;
    Wait for user input. Assume you are the user and you type 5000 and Enter. Then data is filled with the number 5000.

    Output:
    This program is designed to record up to 50 scores between the values of 0 and 100. The scores will then be stored in another file. Please enter all of the needed scores and type -1337 to end the program and store the values.

    Enter an integer (1337 to end input):
    1. 87
    Enter an integer (1337 to end input): 90
    Enter an integer (1337 to end input): 5000
    Code:
    		}
    Continue back up to the top of the while loop.

    Can you see how it is stuck in this while loop until you hit the sentinel, and how it never displays the number anymore?
    Last edited by jlou; 01-08-2004 at 09:53 PM.

  9. #9
    Registered User fjf314's Avatar
    Join Date
    Jan 2004
    Posts
    13
    Yes, and I can't thank you enough! Along with your help and that of some of my classmates today, I finally have this program running. With a better understanding of the code, I was able to make it a lot shorter, too. Here is my revised program:

    Code:
    #include<iostream.h>
    #include<iomanip.h>
    #include<fstream.h>
    
    const int SENTINEL = -1;
    const int max_score = 51;
    
    
    int main()
    {
    
    	int data;
    	int number;
    	ofstream out_file;
    
    	number = 1;
    	
    	out_file.open("stat_data");
    
    	cout << "This program is designed to record up to 50 scores between the values of 0 and";
    	cout << " 100.  The scores will then be stored in another file.  Please enter all of";
    	cout << " the needed scores and type -1 to end the program and store the values.";
    	cout << endl << endl;
    
    	
    	while ( data != SENTINEL && number < max_score )
    	{
    
    		cout << number << ". ";
    		cout << "Enter an integer (-1 to end input): ";
    		cin >> data;
    
    		number = number++;
    
    	
    		while ( data != SENTINEL && data < 0 || data > 100 && number < max_score )
    		{
    					
    			cout << "\nThe number entered was not within the parameters.  Please try again: ";
    			cin >> data;
    			
    		}
    
    	
    		if (data != SENTINEL )
    		{
    			out_file << data << " \n";
    		}
    		
    		if ( number > max_score )
    		{
    			cout << "The program cannot store anymore numbers.  Please enter -1 to end: ";
    			cin >> data;
    		}
    	}
    	
    	out_file.close();
    	return 0;
    }
    My only real question now (and it's more out of curiosity, since my program is working) is why my max_score constant needs to be set to 51. While I was testing the program, I just set it to 5, but then it cut off after 4 numbers were entered. I have to make the maximum one number larger than what I actually want the maximum to be. Still, that's a minor thing. Thanks again for the help.

  10. #10
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Originally posted by fjf314
    My only real question now (and it's more out of curiosity, since my program is working) is why my max_score constant needs to be set to 51. While I was testing the program, I just set it to 5, but then it cut off after 4 numbers were entered. I have to make the maximum one number larger than what I actually want the maximum to be. Still, that's a minor thing. Thanks again for the help.
    Congratulations. As for your question, your first while loop checks number < max_score, so if number is 5 and max_score is 5, it will stop. If you used number <= max_score, it'd probably work as expected.

    Also, I don't see that you initialized data. I'd change:
    Code:
    int data;
    int number;
    ofstream out_file;
    
    number = 1;
    
    out_file.open("stat_data");
    to
    Code:
    int data = 0;
    int number = 1;
    ofstream out_file("stat_data");

  11. #11
    Registered User fjf314's Avatar
    Join Date
    Jan 2004
    Posts
    13
    Thanks yet again. I guess I missed the initialization section of your earlier post. Yes, I was just getting lucky and my compiler was setting my SENTINEL at something it wasn't equal to and my number at 0. That's also taken care of, now, and the program works like a charm. Thanks for all of the help.
    Programming With: Microsoft Visual C++ 6.0

Popular pages Recent additions subscribe to a feed