Assigning and Displaying Array Values


The following program shows how to assign values to an array, one element at a time. The assignment starts with the first index, 0, and ends with the last index, 2, which is one less than the number of elements, 3. The program then outputs the array values, one at a time.

 #include <iostream> using namespace std; int main () {  int testScore[3];  cout << "Enter test score #1: ";  cin >> testScore[0];  cout << "Enter test score #2: ";  cin >> testScore[1];  cout << "Enter test score #3: ";  cin >> testScore[2];  cout << "Test score #1: " << testScore[0] << endl;  cout << "Test score #2: " << testScore[1] << endl;  cout << "Test score #3: " << testScore[2] << endl;  return 0; } 

Some sample input and output could be:

 Enter test score #1: 77 Enter test score #2: 91 Enter test score #3: 84 Test score #1: 77 Test score #2: 91 Test score #3: 84 

However, this one-element-at-a-time approach has no advantage over the following program, which does not use an array at all, but just three separate variables :

 #include <iostream> using namespace std; int main () {  int testScore1, testScore2, testScore3;  cout << "Enter test score #1: ";  cin >> testScore1;  cout << "Enter test score #2: ";  cin >> testScore2;  cout << "Enter test score #3: ";  cin >> testScore3;  cout << "Test score #1: " << testScore1 << endl;  cout << "Test score #2: " << testScore2 << endl;  cout << "Test score #3: " << testScore3 << endl;  return 0; } 

The advantage of an array over using separate variables is the ability to use a loop. This is shown by the following program:

 #include <iostream> using namespace std; int main () {  int testScore[3];  for (int i = 0; i < 3; i++)  {  cout << "Enter test score #" << i + 1 << ": ";  cin >> testScore[i];  }  for (i = 0; i < 3; i++)  {  cout << "Test score #" << i + 1 << ": "  << testScore[i] << endl;  }  return 0; } 

Better yet, you can use a constant instead of an integer literal for the number of array elements:

 #include <iostream> using namespace std; const int MAX = 3; int main () {  int testScore[MAX];  for (int i = 0; i < MAX; i++)  {  cout << "Enter test score #" << i + 1 << ": ";  cin >> testScore[i];  }  for (i = 0; i < MAX; i++)  {  cout << "Test score #" << i + 1 << ": "  << testScore[i] << endl;  }  return 0; } 

This example illustrates an advantage of using constants rather than literals for the size declarator. Assume I wrote this program to keep track of a student s test grades at a time when my policy is to give three tests during a semester. However, later I change my policy to giving five tests during a semester. Since I used a constant as a size declarator, I only need to make one code change, which is to initialize the constant MAX to 5 instead of 3. In contrast, had I instead used the numeric literal 3 as the size declarator, I have to find that number each time it is referred to in the program, once in the array declaration, and once each in the two for loops . This means only three changes, but in a more complex program the number could be much higher. Not only is this time-consuming , but the potential exists that I could miss a reference to 3 which I needed to change to 5.

In this example, the constant MAX is global. However, making the constant MAX global is not contrary to my recommendation in Chapter 9 against making variables global. The primary reason for my recommendation against global variables is that a global variable may be changed from anywhere in the program, making it more difficult to trace ”for example, why such a variable has an incorrect value. By contrast, the value of a constant cannot be changed at all. Consequently, the reason for the recommendation that a variable should not be global simply does not apply to a constant. Therefore, global constants, as opposed to global variables, are relatively common.

However, whether you use a constant or an integer literal for the number of array elements, you must take care not to go beyond the bounds of the array. The following program demonstrates a common programming mistake.

 #include <iostream> using namespace std; const int MAX = 3; int main () {  int testScore[MAX];  for (int i = 0; i <= MAX; i++)  {  cout << "Enter test score #" << i + 1 << ":";  cin >> testScore[i];  }  for (i = 0; i <= 3; i++)  {  cout << "Test score #" << i + 1 << ": "  << testScore[i] << endl;  }  return 0; } 

This program is the same as the previous program, expect that the relational operator in the condition of each for loop has been changed from < to <=. The result is an attempt to access index 3 of the array. The problem, of course, is that there is no such index in a three-element array; the last index is 2. The result depends on the particular compiler and operating system, varying from weird output to run-time errors to the computer locking up, but the result is never good.

Using the cin and cout Objects with Arrays

You can assign values to a character array using the same technique as you used in the previous section to assign values to an integer array:

 #include <iostream> using namespace std; const int MAX = 3; int main () {  char grades[MAX];  for (int i = 0; i < MAX; i++)  {  cout << "Enter grade for test #" << i + 1 << ":";  cin >> grades[i];  }  return 0; } 

This technique is a logical choice when each element of the array is separate from the other, such as a separate grade for each test. However, sometimes the character array elements are related , such as a character array representing a person s name .

As discussed previously in this chapter in connection with initialization, there are important differences between character arrays and arrays of numeric data types. Another difference is the ability to use the cin object and the stream extraction operator >> to assign a value to all elements of a character array, and the cout object and the stream insertion operator << to display the values of all elements of a character array. This is demonstrated by the following program:

 #include <iostream> using namespace std; int main () {  char name[ 80] = {'J', 'e', 'f', 'f', '/0' };  cout << "Enter your name: ";  cin >> name;  cout << "Your name is " << name;  return 0; } 

Some sample input and output could be

 Enter your name: Jeff Your name is Jeff 

This approach has the advantage of not requiring two loops for input and display, respectively. The assignment takes place in one step with the cin object and the stream extraction >> operator. Similarly, the display takes place in one step with the cout object and the stream insertion << operator.

Using the cout Object with Numeric Arrays

You can use the cout object and the stream insertion << operator with a numeric array rather than a character array without experiencing a compiler or run-time error, but you will likely not get the result you expect. The following program modifies a previous one by, instead of using a second loop to display test scores, attempting to display the test scores in one step with the cout object and the stream insertion << operator.

 #include <iostream> using namespace std; const int MAX = 3; int main () {  int testScore[MAX];  for (int i = 0; i < MAX; i++)  {  cout << "Enter test score #" << i + 1 << ": ";  cin >> testScore[i];  }  cout << "The test scores are: " << testScore;  return 0; } 

Some sample input and output could be

 Enter test score #1: 76 Enter test score #2: 84 Enter test score #3: 91 The test scores are: 0012FECC 

What happened is that the value of the name of the array is the base address of the array. Therefore, the output of cout << testScore is the base address of the testScor e array, which happens to be the hexadecimal address 0012FECC.

This explains why you obtain an address rather that array values when you use the stream insertion operator << with a numeric array. However, it does not explain why you obtain array values rather than an address when you use the stream insertion operator << with a character array. After all, the name of a character array, like the name of a numeric array, is a constant whose value is the base address of the array.

The answer simply is that the C++ programming language treats the stream extraction operator >> differently with a character array than with a numeric array. When so used, the character array name is not interpreted as a constant whose value is the base address of the array, but rather the starting point for display. This is just another example of the differences between character arrays and numeric arrays.

Using the cin Object with Numeric Arrays Not!

While you can use the cout object and the stream insertion operator << with numeric arrays as well as character arrays (albeit with different results), you can use the cin object and the stream extraction operator >> only with a character array. You cannot use the cin object and the stream extraction operator >> with numeric arrays. This is demonstrated by the following program:

 #include <iostream> using namespace std; const int MAX = 3; int main () {  int testScore[MAX];  cin >> testScore;  return 0; } 

The result is a compiler error. The compiler will highlight the statement cin >> testScore and complain that the stream extraction operator >> cannot have a right-hand operand that is an integer array.

This compiler error may sound familiar. Previously in this chapter, an attempt to use the stream extraction operator to assign a value to the constant, such as cin >> numTests when numTests was an integer constant, resulted in a compiler error, the message being that the stream extraction operator >> cannot have a right-hand operand that is a constant.

This is essentially the same problem. As you will learn more about in Chapter 11, the name of the integer array, testScore, is a constant whose value is the base address of the array.

While this explains why you can t use the stream extraction operator >> with an integer array, you may now be wondering why you can use the stream extraction operator >> with a character array since the name of a character array, like the name of an integer array, is a constant whose value is the base address of the array. The answer is essentially the same as the one to the similar question in the preceding section regarding the stream insertion operator <<. The C++ programming language supports use of the stream extraction operator >> with a character array. When so used, the character array name is not interpreted as a constant whose value is the base address of the array. This is just another example of how the C++ programming language treats character arrays differently than arrays of other data types.

The cin Object s getline Function

The following program from the previous section worked fine when the input had no embedded spaces, such as Jeff.

 #include <iostream> using namespace std; int main () {  char name[ 80] = {'J', 'e', 'f', 'f', '/0' };  cout << "Enter your name: ";  cin >> name;  cout << "Your name is " << name;  return 0; } 

However, examine the following sample input and output:

 Enter your name: Jeff Kent Your name is Jeff 

We examined this same issue in Chapter 3 with the following program, which used a string variable instead of a character array:

 #include <iostream> using namespace std; #include <string> int main(void) {  string name;  cout << "Enter your name: ";  cin >> name;  cout << "Your name is " << name;  return 0; } 

The explanation in Chapter 3 of why the value of name is outputted only as Jeff , omitting Kent , is that the cin object interprets the space between Jeff and Kent as indicating that the user has finished inputting the value of the name variable. The solution is to use the getline function of the cin object.

Note  

The cin object also has a get function that would solve this issue. The only difference between the two is that the get function reads the user s input up to, but not including, the newline character (the ENTER key that terminates input, whereas the getline function reads the user s input up to and including the newline character. This difference makes the getline function easier to use than the get function when working with character arrays. The get function usually is used with single characters , not character arrays.

The getline function of the cin object is overloaded. By overloaded I do not mean overworked. Rather, the term overloaded when used in connection with the function means the function may be called more than one way, each way differing by the number, data type, or order of arguments.

The following program uses the getline function to read the user s input and assign that input to the character array:

 #include <iostream> using namespace std; int main () {  char name[80] = {'J', 'e', 'f', 'f', '/0' };  cout << "Enter your name: ";  cin.getline(name, 80);  cout << "Your name is " << name;  return 0; } 

Now, as shown by the following sample input and output, you can input a string such as Jeff Kent that includes an embedded space:

 Enter your name: Jeff Kent Your name is Jeff 

The first argument is the name of the character array into which the input will be stored. The second argument is one more than the number of characters that will be read from standard input, here the keyboard. Since the second argument is 80, the number of characters that will be read from standard input is 79, the 80 th character saved for the null character. Since the declared size of the character array in this example is 80, and one element is needed for the null character, that leaves 79 characters for user input.

Another variant of the overloaded getline function has three arguments, such as in the following example:

 cin.get(name, 80, '\n'); 

The third argument is the character that should terminate the reading in of input if it is encountered before the number of characters specified in the second argument. Here the third argument is the newline character, created when the user presses the ENTER key. Since the pressing of the ENTER key will end input anyway, the third argument of ˜\n often is superfluous. However, you could use another character as the third argument if it fits the needs of your program.

You cannot use the get or getline functions of the cin object with strings. Instead, you use the standalone getline function. By standalone, I mean the getline function is not called with a preceding cin and a dot ( cin.getline ) as in the case of character arrays.

The following code fragment shows how to use the getline function with a string:

 String name;  getline(cin, name); 

The first argument is the cin object. The second argument is the string into which the input will be stored. Since you do not have to specify the size of a string, there is no argument limiting the number of characters for input.




C++ Demystified(c) A Self-Teaching Guide
C++ Demystified(c) A Self-Teaching Guide
ISBN: 72253703
EAN: N/A
Year: 2006
Pages: 148

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net