CSCI 15A Jim Murphy We have seen how to check for certain conditions using the if, if ... else, and switch statements but to repeat some process until we get it correct as in giving name and PIN at the ATM machine we need looping - ability to repeat part of our code some number of times For this we can use the "while loop" as: while (condition) { iterative part } For example we could use the bank class and ATM: #include "ouratm.h" #include "ourbank.h" int main( ) { bank BofCS; ATM myatm; int custNum, found = FALSE; while (!found) { myatm.getNameAndPIN( ); BofCS.findCustomer(myatm, custNum, found); if (!found) myatm.message ("Not a valid name and PIN try again."); } It is possible that you may know ahead of time how many times you want to execute a loop - or the end user may know and could be asked as in: p241.cpp // Using this while loop averaging method, the user // must know in advance, the number of input values // that are to be averaged #include int main() { int number; // Initialize sum, counter, and n: float sum = 0; int counter = 1; int n; cout << "Enter number of entries to be averaged: "; cin >> n; // While there are more numbers to be averaged while(counter <= n) { // Execute this block n times: cout << "Enter number “<> number; // <- three sum = sum + number; // <-statements // counter holds the number of loop repetitions. // counter is incremented n times. // When counter exceeds n // (counter <= n is false), the loop is terminated. counter = counter + 1; } float average = sum / float(n); 100.0*isum/n cout << endl << " Average: " << average << endl; return 0; } make p241 then run with: p241 Enter number of entries to be averaged: 4 Enter number: 60 Enter number: 65 Enter number: 70 Enter number: 75 Average: 67.5 If the while condition is true then the iterative part is executed once then the condition is evaluated again This keeps up until the condition is false at which point the iterative part is not executed int x = 0; while (x < 10) { cout << x << endl; x = x + 1; } cout << x << endl; while (*(x++)=*(y++));// ok to copy until null character { cout << “ oh my “ << endl; x = x + 1; } LESSON 10 A counter controlled loop can be used if the number of iterations is known at program writing as in: src/p243.cpp #include int main() { // Iterate a loop n times int n = 4; int counter = 1; while(counter <= n) { // The repeated process outputs the changing // value of counter: cout << "Iteration# " << counter << endl; // // The counter is incremented to eventually // terminate the loop: counter = counter + 1; } cout << "After loop, counter = " << counter << endl; return 0; } p243 Iteration# 1 Iteration# 2 Iteration# 3 Iteration# 4 After loop, counter = 5 Another example adds up the first n integers where n is set to 5 in the example from: src/p244.cpp // An example of a counter-controlled while loop #include int main() { // Initialize the objects used in the while loop int n = 5; int accumulator = 0; int counter = 1; // The counter controlled while loop while(counter <= n) { accumulator = accumulator + counter; counter = counter + 1; } cout << "Sum of the first " << n << " integers is " << accumulator; return 0; } p244 Sum of the first 5 integers is 15pitbull 24> Note the missing endl on the last cout statement Watch out for missing brackets which is allowed but may not be what was intended as in: int counter = 1; while (counter <=20) cout << counter << endl; counter = counter + 1; // never executed The case study on pages 248 to 253 considers the problem of finding the range of a large collection of numbers - for a small set of numbers it is easy for us to pick out the largest and smallest numbers present visually - for a large set of numbers we need an algorithm Take the first number on the list as the only contender and consider it to be both the largest and the smallest Certainly true if there was only this one number on the list - then as each new number is added to the list compare it to the largest-so-far and the smallest-so-far adjusting those values if necessary these int objects are actually called highestTest and lowestTest in the program on page 252 This program will find the largest and smallest value in a collection of numbers and then compute the range to be (largest - smallest) src/p252.cpp #include int main() { int test, highestTest, lowestTest; int testsToCheck; cout << "Enter number of test scores: "; cin >> testsToCheck; cout<> test; highestTest = test; lowestTest = test; // We have processed one check, so start counter at 2. int counter = 2; while(counter <= testsToCheck) { cin >> test; if(test > highestTest) highestTest = test; else if(test < lowestTest) lowestTest = test; counter = counter + 1; } int range = highestTest - lowestTest; cout << "Range: " << range; return 0; } It may be more convenient to let the computer figure out how many data entries there will be rather than asking the user for that number - The machine is good at counting if it just had some way of knowing when we were done entering numbers - sometimes it is possible to use a special data value called a "sentinel" or signal - if there is a value which is guaranteed not to be normal data then we could use that as is done in the program on page 256 which computes the average of a collection of positive integers using a sentinel value of minus one src/p256.cpp watches for a special data value to stop // Use a sentinel of -1 to terminate a loop. // A sentinel is a value that cannot be within the range // of valid data. It is the final input indicating there // is no more data. The extraction of this // sentinel value is the event that terminates the loop. #include int main() { // PRE: The user enters at least one valid int != -1 const int sentinel = -1; int testScore; float accumulator = 0; int n = 0; // Incremented for every input != -1 // Display a prompt cout << "Enter test scores or " << sentinel << " to quit" << endl; // This next statement is used to obtain // a value for the loop-test cin >> testScore; while(testScore != sentinel) { accumulator = accumulator + testScore; // Update the accumulator n = n + 1; // Update total inputs cin >> testScore; // Input next test or the sentinel } cout << endl << "Average of " << n << " tests = " << (accumulator / n) << endl; return 0; } make p256 then execute with: p256 Enter test scores or -1 to quit 50 55 60 65 70 -1 Average of 5 tests = 60 Note the order of the statements in and around the while loop - the existence of the two cin statements and where the counter and accumulator are incremented What would happen if we entered -1 at the first cin? cin >> testScore ; this returns true if successful and false (0) if it fails so we could use: while ( (cin >> testScore)&&(testScore!=sentinel)) Note what happens if you type in a letter like "q" which is not a valid int Any input asked for once cin gets into a bad state will fail unless the input stream is reset with the flush(cin); function from ourstuff.h shown next: src/p260.cpp // Demonstrate what happens when an input stream // is in an error state #include #include "ourstuff.h" // for flush(cin) int main() { double testScore; double sum = 0; double n = 0; cout << "Enter test scores or -1 to quit" << endl; while( ((cin >> testScore)!= 0) && (testScore != -1) ) { sum = sum + testScore; n = n + 1; } cout << "Ave: " << (sum / n) << endl; // Demonstrate flush(cin) to allow further input // ... flush(cin); cout << "Enter another testScore: "; cin >> testScore; cout << "testScore: " << testScore << endl; cout << "and one more: "; cin >> testScore; cout << "testScore: " << testScore << endl; return 0; } p260 Enter test scores or -1 to quit 50 55 60 -1 Ave: 55 Enter another testScore: 40 testScore: 40 and one more: 55 testScore: 55 When using input from a data file we can use the eof or end-of-file function to terminate our entry loop We input several one word strings from a text file cat src/p262.cpp #include #include #include "ourstr.h" int main() { ifstream inFile("input.dat"); cout << "Before loop, eof = " << inFile.eof() << endl; string s; while(! inFile.eof()) { inFile >> s; s.toUpper(); cout << "s = " << s << endl; } cout << " After loop, eof = " << inFile.eof() << endl; return 0; } cat src/input.dat Several strings on two lines.pitbull 39> p262 Before loop, eof = 0 s = SEVERAL s = STRINGS s = ON s = TWO s = LINES. After loop, eof = 1 LESSON 11 But look out if the input file is not in the current directory - this will cause an error also and an infinite loop - use control C to interrupt the program in this case - from home control S and control Q will start and stop output but not the program To use eof with keyboard input such as cin you will need to enter control D on a unix system but control Z on DOS - you will also need to use flush(cin) after the eof is encountered as it will mess up subsequent keyboard input