4. Numbers, strings and loops

Review Topics


General Information

Housekeeping

  • Make sure you follow along with this page linked in Canvas
  • Please keep your microphone off unless you are asking a question
  • Please turn on camera if you can (optional)
  • Use chat if you would like to comment or ask questions

Announcements

See Announcements link in Canvas to keep up with what is going on. Here are a few for review:

  • Remember that PAs and the Individual Readiness Assurance Quiz are due before class on Tuesday.
  • Remember to post in the Pair programming partners discussion group if you need a partner
  • Remember that the exercises from this page are due Sunday at 9:00pm.
  • Remember that CAs, Labs, and Class Exercises may be completed up to two days late but with a 10%/day penalty.
  • Remember to complete the LockDown Browser Practice quiz--required for exams
  • Some lab solutions posted in Canvas Modules
  • Free Fresh Market schedule: free fresh fruits and vegetables
  • Food & Housing Resources: free food, meals, temporary and permanent housing
  • COVID-19 Resources and Information: Includes loaner-laptop information
  • Campus WiFi Access

Homework Help

4.1: Readiness Assessment Quizzes

  • Reading and participation activities are due before the first class meeting of the week
  • Quizzes assess the comprehension of the reading and participation activities

Quiz Part 1: Individual Readiness Assessment

  • Complete this quiz solo to assess your reading comprehension and readiness
  • Must take this quiz before the first class meeting of the week to ensure you are ready for the team quiz
  • Quiz is open book and notes but timed
  • Highest score is counted so take the quiz multiple times

Quiz Part 2: Team Readiness Assessment (20m)

  • Must attend the class meeting to take this quiz
  • Login to Canvas
  • Will move to breakout rooms with your team
  • Make sure you have the access code for the exam
  • Openly discuss what you believe to be the best answers for the questions
  • Decide how to agree on the answers
    • Strive to reach a consensus on quiz answers
    • If no consensus, work it out as you and others in your group see fit
  • Turn in the quiz as a group
  • Each group member will receive the same score
  • Return to the main meeting room when finished

Quiz Appeals

  • After completing the team quiz, team members may appeal an answer
  • Appeals can be based on two criteria:
    1. Question is factually wrong

      Appeal must included citations to sources of information that document or support an alternative answer. Team may access reference materials during the appeal.

    2. Question is confusing based on it's wording

      Appeal must include an appropriate rewrite of questions or answers that you interpret as ambiguous or confusing.

  • Work with teammates to develop and write any appeals
  • Team has up to 24 hours after the quiz to email appeal to instructor
  • If appeal is granted, only the teams that submitted appeal gets credit

4.2: Compiling revisited

  • Many students are turning in lab projects with problems that can be detected by the compiler.
  • By detecting and fixing these problems students will get a higher score.

4.2.1: Compiling with warnings enabled.

To find more problems in our code use the following command in the terminal window of Repl.it:

g++ -Wall -Wextra -Wpedantic -o main main.cpp

Where the parts of the command mean:

  • g++: The name of the compiler program
  • -Wall: Enable all the warnings about questionable code (like /* /* */)
  • -Wextra: Print extra warning messages for some problems (like unused-parameters)
  • -Wpedantic: Show all the warnings demanded by strict ISO compliance
  • -o main: After -o type the name of our executable file
  • main.cpp: The name of our source code file, which must end in .cpp

To run a compiled program in the terminal window we enter:

./main

Exercise 4.2: Debugging a Program (12m)

For this exercise we break into teams. Within the team, work with each other to develop a solution. When the team has finished, Choose one member to show your solution to the class by sharing your screen. The instructor will ask one team to share their solution.

In this exercise we practice finding and fixing errors with warnings enabled in our compiler starting with the following program:

Erroneous Program

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
    A very erroneous program.

    @author B. A. Ware
    @version 1.1 2/14/21

#include <iostrea m>
using namespace standard;

/**
 * The main functoin for the program.
 */
int main() {
    double trouble;
    cout <<< "Hell out there.\";
    cout << "Enter a number as a percent: "
    cin << ware;
    Cout << "As a double the number is: ";
    cout << ware / 00 << end1;
    cout << "Double trouble=" << trouble * trouble << endl;
    return;
}} / / end of main

Specifications

  1. Start Repl.it and copy into it the above code.
  2. Correct the compiling errors using the  Run ▶  button.
  3. Now compile by entering the following command into the terminal window:
    g++ -Wall -Wextra -Wpedantic -o main main.cpp
    
  4. Correct the new errors discovered by the compiler warnings.
  5. Verify the program has the correct output for a given input:
    Hello out there.
    Enter a number as a percent: 75
    As a double the number is: 0.75
    Double trouble=84
    
  6. Next look over the code and correct spelling errors.
  7. Once satisfied with your code, copy your code into a text editor, save the file as "errfix.cpp", and submit the file to Canvas with the rest of the exercise files for the week.

When finished developing your code click hereClick to show answer to verify. Code need not look exactly the same. After you have completed your own program, reviewing another is often helpful in learning how to improve your programming skills.

4.3: More About Variables and Numbers

In this section we cover more of the numerical features of C++.

4.3.1: Changing types

Cast: change the data type of a value in an expression

  • Recall that different data types are stored in different forms
  • Sometimes we need to change from one form to another
  • For example, arithmetic adding a double and an int value
  • C++ will automatically change one value to another
    • Known as implicit casting or "type coercion"
  • Programmers may explicitly cast data types using a cast operator
    static_cast<toType>(expression)
    
  • For example:
    double a = 2.99999;
    double b = static_cast<int>(a);
    double diff = a - b;
    cout << "a=" << a << " b=" << b
         << "\ndiff=" << diff << endl;
    
  • The value of a is converted from type double to int before assigning the converted value to b
  • However, a remains a type double and the cast only applies to a single use of a
  • The above example shows a common use of casting -- removing the decimal part of a floating-point number
  • Note that the decimal portion of the number is truncated and NOT rounded
  • The decimal part is lost (discarded, ignored, thrown away)

Other Uses for Casting

  • Consider the following code:
    int degF = 70;
    int degC =  5 / 9 * (degF - 32);
    cout << degF << "F is " << degC << "C" << endl;
    
  • What is the problem with the above code?
  • To correct the problem we can use a cast, like:
    int degF = 70;
    int degC =  static_cast<double>(5) / 9 * (degF - 32);
    cout << degF << "F is " << degC << "C" << endl;
    
  • The value 5 is converted from type int to double before the integer division
  • Still another use for casting is to convert a number to a character
    int x = 65;
    cout << x << " is " << static_cast<char>(x) << endl;
    

Example Application Using Casting: cast.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;

int main() {
    double input;
    cout << "Enter hours: ";
    cin >> input;

    int hours = input;
    int minutes = (input - static_cast<int>(input)) * 60;
    cout << "In hours and minutes, this is "
         << hours << ":" << minutes << endl;
    return 0;
}

Check Yourself

  1. True or false: the reason for using a typecast is to temporarily convert the type of a value.
  2. Of the following, ________ is a valid typecast.
    1. static_cast<a>(int)
    2. int:a;
    3. static_cast<int>(a)
    4. to(int, a);
  3. True or false: type casting permanently changes the type of a variable.

4.3.2: Exponential Notation

  • Floating-point numbers can be written in exponential notation, also known as scientific notation
  • In exponential notation, we express repeated multiplication using an exponent
  • For example, we write 10 • 10 • 10 as 103, which is a more compact form
  • The number being multiplied is the base and the power the base is being raised to is the exponent

    base   103   ← exponent

  • 103 is read as "10 to the third power" or "10 cubed" and means 10 • 10 • 10, or 1,000.
  • Exponential notations lets us express both very large and very small values in a compact form

Converting from and to Exponential Notation

  • We can easily convert a number in exponential form to standard form by moving the decimal place
  • A positive power of 10 moves the decimal point to the right
  • For example, the number 1.234 x 103 can be returned to standard form by moving the decimal 3 places to the right:
    1.234 x 103 1234
  • A negative power of 10 moves the decimal point to the left
  • Thus, we can convert 1.234 x 10-3 to standard form by moving the decimal place 3 places to the left:
    1.234 x 10-3 0.001234
  • We can convert to exponential notation by reversing the process

Examples of Exponential Notation

Decimal Form Exponential Form C++ Form
1234 1.234 x 103 1.234e3
98765 9.8765 x 104 9.87654e4
0.0123 1.23 x 10-2 1.23e-2
0.000625 6.25 x 10-4 6.25e-4

Exponential Notation in C++

  • Notice that in C++ we represent the x10 part as e or E
  • We cannot easily express an exponent in source code with standard math notation
  • Instead we substitute E for "times ten raised to the power" like: 1.234 x 103 1.234E3
  • The letter e stands for exponent
  • The number following the e is the power of 10 to multiply the first number by
  • Thus, "e" means "times ten raised to the power"

Activity: Exponential Notation

  1. Open a text editor.
  2. Express the following quantities in C++ exponential notation: (3m)
    1. The population of the world is about 7,744,000,000. (source: census.gov)
    2. The distance from Earth to the Sun is about 92,960,000 miles.
    3. The human body contains approximately 60,000,000,000,000 to 90,000,000,000,000 cells.
    4. The mass of a particle of dust is about 0.0000000266 ounces.
    5. The length of the shortest wavelength of visible light (violet) is 0.0000004 meters.
  3. When finished, we will review the numbers.

How Large is 1.7E308?

  • The largest possible double number is 17 followed by 307 zeros
  • How large is that?
  • The current estimate of the number of atoms in the universe is between 1.0e79 to 1.0e81
  • Mathematicians use the term "googol" for a very large number: 1.0e100
  • Data type double easily encompasses these numbers
  • What large number cannot be represented by type double?

Check Yourself

  1. True or false: one advantage of exponential notation is that you can compactly write very large and very small numbers.
  2. Write the number one billion (1,000,000,000) in exponential notation.

    answer

  3. Write the number one millionth (0.000001) in exponential notation.

    answer

More Information

4.3.3: Decimal Formatting

  • Sometimes programs may not display numbers as we would expect!
  • Consider the following program and what it will display:
    #include<iostream>
    using namespace std;
    
    int main() {
        double price = 78.50;
        cout << "The price is $" << price << endl;
    }
    
  • We must explicitly tell C++ how to output numbers in our programs
  • These commands do not produce any output directly but change how cout outputs floating-point numbers
  • Magic Formula to force decimal places:
    cout << fixed             // fixed notation, not scientific
         << setprecision(2);  // show 2 decimal places
    
  • To use setprecision(), we must include the iomanip library:
    #include <iomanip>
    
  • The commands fixed and setprecision are known as manipulators because they change how cout works
  • We may put all the commands on one line:
    cout << fixed << setprecision(2);
  • Also, we may combine the commands with other output:
    cout << "The price is $"
         << fixed << setprecision(2)
         << price << endl;
    
  • Once we set the decimal formatting, it stays set
  • To restore the default formatting we use:
    cout << defaultfloat << setprecision(6); // 6 is default
    

Check Yourself

  1. The number 1.23 x 1012 is usually formatted by cout as ________.
  2. Rewrite the number 1.23 x 1012 in "normal" fixed notation.

    Hover for answer

  3. Write the code to display 1.23 x 1012 in "normal" fixed notation.

    Hover for answer

  4. Write the code to display $19.90.

    Hover for answer

More Information

  • Textbook sections on Floating-point numbers (double) and Decimal Formatting
  • Input/output manipulators: Available manipulators from cppreference.com
  • manipulators: Available manipulators from cplusplus.com

4.3.4: Assignment Operators

  • As we discussed before, we assign values to variables using an equal (=) sign
    int sum = 0;
  • The "equal sign" is really an assignment operator in C++ and does not denote equality
  • Thus, unlike math, we can have the same variable on both sides of an equals sign:
    int sum = 25;    // initialize sum to 25
    sum = sum + 10;  // add to sum
    
  • In the first line we store the value 25 in the variable sum
  • On the second line we read the value 25 from the variable sum and add 10
  • Adding two values does not change the value of the variable
  • Instead we must assign the new value (35) to the variable using the assignment operator (=)
  • Values placed into a variable replace (overwrite) previous values:

    Assigning a value to a variable

Compound Assignment Operators

  • C++ has additional assignment operators that combine other operators with assignment
    • Known as compound assignment operators
  • The general syntax is:
    variable op= expression;
  • Where op is an operator like one of the five arithmetic operators: +, -, *, /, %
  • For example, the following two statements create the same result:
    x = x + 3;
    x += 3;
    
  • Shown below are some assignment operators with examples of how they are used

Summary of Assignment Operators Used in Arithmetic Operations

Operator Description Example Equivalent To
= Assigns the value of the expression on the right to the variable on the left x = 3  
+= Adds the expression on the right to the variable on the left x += 3 x = x + 3
-= Subtracts the expression on the right from the variable on the left x -= 3 x = x - 3
*= Multiplies the expression on the right to the variable on the left and saves the result in the variable on the left x *= 3 x = x * 3
/= Divides the variable on the left by the expression on the right and saves the result in the variable on the left x /= 3 x = x / 3
%= Calculates the remainder from dividing variable on the left by the expression on the right and saves the result in the variable on the left x %= 3 x = x % 3

Increment and Decrement Operators

  • Adding or subtracting one is a common operation in programming
  • C++ provides arithmetic shortcuts for these operations with the increment and decrement operators
  • The increment operator (++) adds 1 to a variable's value
  • Preincrement adds 1 before evaluating an expression
    ++sum;
  • Post-increment evaluates the expression and then adds 1
    sum++;
  • The decrement operator works like the increments operator, except it subtracts 1 from the variable:
    --sum
    sum--
    

When Pre- and Post- Increment Matters (Optional)

  • Pre- and post- increment matters when the operation is part of a larger expression
  • For example, consider the code:
    int x = 5;
    int y = x++;
    cout << "x=" << x << " y=" << y << endl;
    
  • We may expect y to be 6 after this code executes
  • Instead, y has the value of 5
  • The reason is that ++ after a variable (post-increment) is equivalent to:
    y = x;
    x = x + 1;
    
  • On the other hand, ++ before a variable (pre-increment) is equivalent to:
    x = x + 1;
    y = x;
    
  • Note that mixing pre- and post-increment with the same variable is not allowed, like ++i++
  • Also, expressions that read and update a variable twice, like i++ + i++, is undefined
  • Undefined means that not all C++ compilers will produce the same results

More Information

Activity: Add One (1m)

In chat, list all the ways to add the integer 1 to a variable named c.

Check Yourself

  1. The value of count after the following code executes is ________.
    int count = 0;
    count = count + 1;
    
  2. What is an equivalent statement for each of the following shortcut assignments?
    1. a += b;(answer)
    2. a -= b;(answer)
    3. a *= b;(answer)
    4. a /= b;(answer)
    5. a %= b;(answer)
  3. List four ways to add the integer 1 to a variable named c.

Exercise 4.3: Exploring Numeric Features of C++ (15m)

In this exercise we explore some additional numeric features of C++.

For this exercise we break into teams. Within the team, work with each other to develop a solution. When the team has finished, Choose one member to show your solution to the class by sharing your screen. The instructor will ask one team to share their solution.

Specifications

  1. Start Repl.it and copy the following program into its text editor.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    int main() {
        string name;
        double price = 0;
    
        cout << "Enter the product name: ";
        cin >> name;
        cout << "Price of the " << name << ": ";
        cin >> price;
    
        // Insert new statements here
    
        cout << "Total price: $" << price << endl;
    
        return 0;
    }
    
  2. Compile and run the starter program to make sure you entered it correctly.

    When you run the program, the output should look like this:

    Enter the product name: iPhone
    Price of the iPhone: 149.50
    Total price: $149.5
    

    Note the format of the numbers output for the total price. We will address this formatting issue later in the exercise.

  3. Run the program again for a product with a very high cost, like a Boeing 777:
    Enter the product name: Boeing__777
    Price of the Boeing_777: 277345678
    Total price: $2.77346e+08
    

    Note the format of the numbers output for the total price is in exponential notation.

  4. Let us correct the formatting of the total price. Enter the following code before the statement that prints the total price:
    cout << fixed             // fixed notation, not scientific
         << setprecision(2);  // show 2 decimal places
    

    These statements are referred to as the "magic formula" because they magically tell C++ to output statements in a "standard" format. Note what each statement accomplishes.

  5. Compile and run your program again and verify the output looks like:
    Enter the product name: Boeing_777
    Price of the Boeing__777: 277345678
    Total price: $277345678.00
    
  6. Let us add a constant that we will use later in our program. Enter the following code after the magic formula and before the statement that prints the total price:
    const int PERCENT = 100;
    

    A constant variable (or constant) is a variable whose value cannot change after being assigned an initial value.

  7. Now we will add sales tax to the price of the product. Enter the following code after the constant and before the statement that prints the total price:
    double taxRate = 0;
    cout << "Enter sales tax rate (%): ";
    cin >> taxRate;
    double tax = price * taxRate / PERCENT;
    price = price + tax;
    

    Notice the last statement: price = price + tax;. This is an alternate way to code the statement: price = price + tax;. For more information, see section: 4.1.5: Assignment Operators.

  8. Compile and run your modified program and verify the output looks like:
    Enter the product name: iPhone
    Price of the iPhone: 149.50
    Enter sales tax rate (%): 9.5
    Total price: $163.70
    
  9. Now we will find the whole dollars and cents of the amount to demonstrate casting. Enter the following code after the statement that prints the total price and before the return statement:
    int dollars = static_cast<int>(price);
    cout << "In whole dollars: $" << dollars << endl;
    

    Notice the (int) in the first statement. This is known as a type cast or just cast. For more information, see section: 4.1.6: Type Casting.

  10. Compile and run your modified program and verify the output looks like:
    Enter the product name: iPhone
    Price of the iPhone: 149.50
    Enter sales tax rate (%): 9.5
    Total price: $163.70
    In whole dollars: $163
    
  11. Once satisfied with your code, copy your code into a text editor, save the file as "prod.cpp", and submit the file to Canvas with the rest of the exercise files for the week.

When finished developing your code click hereClick to show answer to verify. Code need not look exactly the same. After you have completed your own program, reviewing another is often helpful in learning how to improve your programming skills.

4.4: Characters and Strings

Learner Outcomes

At the end of the lesson the student will be able to:

  • Identify characters and strings from their literal representation
  • Assign characters and strings to variables
  • Concatenate strings
  • Collect characters and strings from user input
  • Output characters and strings

4.4.1: Reviewing type char

  • In addition to numbers, computers can manipulate text and other non-numerical types
  • Values of type char (short for character) are a single letter, number or special symbol
  • We write a literal character by enclosing it in single quotes (')
    'a'   'b'   'Z'   '3'   'q'   '$'   '*'
  • The quote marks are not part of the data

ASCII Code

  • When we use a char data type, we store the character using an ASCII code
  • ASCII is a standard that assigns a number to every character
  • Remember that computers store only numbers
  • So to handle text, each character is assigned a number as shown below
  • Each character requires 7-bits, which means it fits within one byte
  • ASCII was the first standardized code but is mostly limited to English
  • In modern times, ASCII has been extended to include all languages
  • The extended ASCII code is called Unicode

ASCII table

Source: Wikimedia Commons

Declaring and Assigning char Variables

  • As with other data types, we must declare char variables before use:
    char letterA;
  • We assign values to a char variable using the equals sign:
    letterA = 'A';
  • Just like numerical types, we may combine definition and assignment into one statement:
    char letterB = 'B';
  • Since char variables are stored as numbers, C++ allows us to assign ASCII code numbers directly
    char letterC = 67;
    cout << letterC << endl;
    

Examples of Declaring and Assigning char Variables

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
using namespace std;

int main()
{
    char letterA;
    letterA = 'A';
    char letterB = 'B';
    char letterC = 67; // 67 is ASCII for 'C'
    cout << letterA << letterB << letterC << endl;
    return 0;
}

User I/O with Type char

  • Like numbers, we can output type char using cout <<
    char letter = 'A';
    cout << letter << 'B' << endl;
    
  • We may input type char using cin >>
    cin >> letter;
    cout << letter  << endl;
    

Simple Arithmetic

  • Since char data types are actually integer numbers, C++ lets us do simple arithmetic
  • For example we can add or subtract integer numbers like:
    char letterE = 'A' + 4;
    char letterD = letterE - 1;
    cout << letterD << letterE << endl;
    

More Information

  • ASCII: ASCII Introduction and History from Harvard CS50.tv (8:02)
  • ASCII: Wikipedia article

Check Yourself

  1. The type of delimiter used to enclose single characters of type char is the ________.
  2. The correct data type for a single character is ________.
    1. character
    2. char
    3. text
    4. string
  3. Which of the following correctly declares a variable for a single character and assigns it a value?
    1. char var = 'z';
    2. char var = 122;
    3. char var = "z";
    4. char var = 'a' + 25;
  4. answer

  5. answer

4.4.2: Reviewing strings

  • In addition to single characters, computers can work with text strings
  • For example, in the following the characters between the double quotes are displayed as text:
    cout << "Hello World!" << endl;
  • Programmers refer to text like this as a string because it is composed of a sequence of characters that we "string together"
  • C++ provides the string data type so we can work with text
  • To work with the string type we may need to include the string library:
    #include <string>
    using namespace std;
    
  • This library is included automatically with <iostream> in our version of clang/g++
  • Literal strings are enclosed in double quotes, with the quotes not part of the string
  • For example:
    "Hello"  "b"  "3.14159"  "$3.95"  "My name is Ed"
  • Notice that the string "3.14159" could be expressed as a double by removing the quotes
  • However, a computer stores these two values very differently and we must use them in different ways
  • For instance, we cannot multiply the "3.14159" by 2, but we can when it is expressed as a double:
    cout << "3.14159" * 2; // NO!
    cout << 3.14159 * 2;   // allowed
    
  • Also note that C++ strings must all be on one line:
    cout << "line one\n // NO!
    line two\n";        // NO!
    
    cout << "line one\n"; // allowed
    cout << "line two\n"; // allowed
    
    cout << "line one\n"  // allowed: no ;
         << "line two\n"; // allowed: last line ;
    

Check Yourself

  1. The type of delimiters used to enclose strings is the ________
  2. True or false: "A" and 'A' are the same.
  3. The name of the string library is ________.
  4. True or false: we can perform arithmetic operations on strings.

4.4.3: String variables and simple I/O

  • We declare and assign values to string variables like numeric types
  • For example:
    string firstName;             // definition
    firstName = "Edward";         // assignment
    string lastName = "Parrish";  // definition + assignment
    cout << firstName << " " << lastName << endl;
    

Simple I/O with Strings

  • Like numbers, we can output type string using cout <<
  • Also, we can input a string using cin >> stringName
  • For example:
    string name;
    cout << "Enter your name: ";
    cin >> name;
    cout << "You entered: " << name  << endl;
    
  • The cin statement assigns the user input to the string variable name
  • Note that only a single word can be entered using cin >> name
  • This is because cin >> name works as follows:
    1. Skips whitespace
    2. Reads non-whitespace characters into the variable
    3. Stops reading when whitespace is found

Check Yourself

  1. True or false: use a string variable rather than a char variable when you may need to store more than one character.
  2. answer

  3. answer

4.4.4: Comparing Characters and Strings

  • Remember that characters can be compared using relational operators
  • Relational operators are useful for making alphabetic comparison between characters, like:
    if ('A' < 'B')
    
  • Since C++ stores characters as numbers using ASCII codes, the computer is actually comparing numbers
    if (65 < 66)
    
  • Remember that letters nearer to the start of the alphabet have lower numerical values than later letters
  • Thus a numerical comparison can decide the alphabetical order of characters
  • Also remember that relational expressions always evaluate to the equivalent of true or false

Comparing Strings

  • We can compare strings using relational operators as well
  • C++ compares two strings using lexicographical order (a.k.a. alphabetic order)
  • Lexicographical order means the comparison is based on the alphabetical order of component letters
  • For example, "car" is less than "cat":
    c a r
    c a t
  • Also, "car" is less than "card"
    c a r
    c a r d
  • We can test string comparisons in the following example program

Example Program Comparing Strings

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
#include<iostream>
using namespace std;

int main() {
    string strOne, strTwo;
    cout << "Enter two words separated by whitespace: ";
    cin >> strOne >> strTwo;
    if (strOne == strTwo) {
        cout << strOne + " == " + strTwo << endl;
    }
    if (strOne != strTwo) {
        cout << strOne + " != " + strTwo << endl;
    }
    if (strOne < strTwo) {
        cout << strOne + " < " + strTwo << endl;
    }
    if (strOne <= strTwo) {
        cout << strOne + " <= " + strTwo << endl;
    }
    if (strOne > strTwo) {
        cout << strOne + " > " + strTwo << endl;
    }
    if (strOne >= strTwo) {
        cout << strOne + " >= " + strTwo << endl;
    }
}

Check Yourself

  1. What is the result of evaluating the following relational expression? (answer)
    'A' < 'B'
  2. What is the result of evaluating the following relational expression? (answer)
    "A" < "B"
  3. Of the following pairs of strings, which comes first in lexicographic order for each of them?
    1. "Harry", "Potter" (answer)
    2. "Harry", "Hairy" (answer)
    3. "car", "C++" (answer)
    4. "car", "Car" (answer)
    5. "car model", "carburetor" (answer)

More Information

Exercise 4.4: Word Guessing Game (12m)

In this exercise we explore the use of equality and relational operators with if statements and strings to create a simple game.

For this exercise we break into teams. Within the team, work with each other to develop a solution. When the team has finished, Choose one member to show your solution to the class by sharing your screen. The instructor will ask one team to share their solution.

Specifications

  1. Start Repl.it and copy the following program into a text editor.
    #include <iostream>
    using namespace std;
    
    int main() {
        string secretWord = "Shazam";
        string userGuess;
    
        cout << "I'm thinking of a secret word, can you guess it?\n\n";
    
        cout << "Enter your word guess: ";
        cin >> userGuess;
    
        // Insert new statements here
    
        return 0;
    }
    
  2. Compile and run the starter program to make sure you entered it correctly.

    When you run the program, the output should look like this:

    I'm thinking of a secret word, can you guess it?
    
    Enter your word guess: abc
    

    Where the input is shown in aqua italics for emphasis.

  3. We want to let the user know if they entered a correct value. For this we need to add an if statement where indicated in the starter code:
    if (userGuess == secretWord) {
        cout << "You guessed the secret word!" << endl;
    }
    

    Notice that we may compare two words using the equality operator.

  4. Compile and run your program again and verify the output looks like:
    I'm thinking of a secret word, can you guess it?
    
    Enter your word guess: Shazam
    You guessed the secret word!
    

    Where the input is shown in aqua italics for emphasis.

  5. For a friendlier game output, we should give the user a message when their guess is later or earlier in the alphabet. For this we replace our if statement with a a series of if-else-if statements like:
    if (userGuess == secretWord) {
        cout << "You guessed the secret word!" << endl;
    } else if (userGuess < secretWord) {
        cout << "Secret word is later in the alphabet." << endl;
    } else {
        cout << "Secret word is earlier in the alphabet." << endl;
    }
    

    Notice that we may compare two words using relational operators. Each letter in the word is compared one after the other in dictionary order.

  6. Compile and run your program again and verify the output looks like:
    I'm thinking of a secret word, can you guess it?
    
    Enter your word guess: Abc123
    Secret word is later in the alphabet.
    

    A hint message should appear for any word other than the correct guess.

  7. Once satisfied with your code, copy your code into a text editor, save the file as "wordguess.cpp", and submit the file to Canvas with the rest of the exercise files for the week.

When finished developing your code click hereClick to show answer to verify. Code need not look exactly the same. After you have completed your own program, reviewing another is often helpful in learning how to improve your programming skills.

4.5: String functions and operations

  • Strings are a special type of variable called objects, which we will study in more detail later in the course
  • Because strings are objects, that have special capabilities in C++

Con + cat + e + nation
Concatenation

4.5.1: Joining Strings (Concatenation)

  • We may join two strings together using the '+' operator
  • The join operation is called concatenation
  • For example:
    string s1 = "Hello", s2 = "World!";
    string s3 = s1 + s2;
    cout << s3 << endl;
    
  • The string s3 now has the contents of both s1 and s2
  • We can also mix string variables and literal strings:
    string s1 = "Hello", s2 = "World!";
    string s3 = s1 + ", " + s2;
    cout << s3 << endl;
    
  • One or both strings surrounding the + must be a string variable
  • For instance, the following will NOT work:
    string greeting = "Hello" + " " + "World!"; // No!
    
  • However, this is not usually a problem because we can just make one long literal string:
    string greeting = "Hello World!";
    
  • In addition, we can concatenate string variables and characters:
    char letter = 'A';
    string s1 = "BC";
    s1 = letter + s1 + 'D';
    
  • However, we cannot concatenate strings with numbers
    string str = "abc";
    str = str + "1"; // allowed
    str = str + '1'; // allowed
    str = str + 1;   // NO
    str = str + 1.2; // NO
    

Check Yourself

  1. The operator used to join two strings is ________.
  2. The value of s3 after the following code executes is ________.
    string s1 = "Hi ", s2 = "Mom!";
    string s3 = s1 + s2;
    
  3. The result of trying to compile and run the following code is ________.
    string s1 = "Hi", s2 = "Mom!";
    string s3 = s1 + " " + s2;
    
  4. The result of trying to compile and run the following code is ________.
    string s1 = "Hi " + " " + "Mom!";
    

4.5.2: String Functions

  • Strings are a special type of variable called objects
  • An object is a data type that can have functions associated with it
  • These functions are called member functions and are called using dot notation
  • The syntax for calling a member function of a string object is:
    stringName.functionName(arguments)
    
  • Where:
    • stringName: the name of the string variable
    • functionName: the name of the member function
    • arguments: the input values, if any
  • Once we create a string variable, we call (invoke) its member functions

Some Commonly-Used Functions

  • length() or size(): Returns the number of characters in a string
    string str = "Hello World!";
    cout << "The number of characters is " << str.size() << ".\n";
    
  • at(pos): Returns the character at position pos
    string str = "Hello";
    char firstChar = str.at(0);
    cout << "The first character is " << firstChar << endl;
    
    The position numbers in a string start at 0. The last character is always one less than the length of the string.
    H e l l o , W o r l d !
    0 1 2 3 4 5 6 7 8 9 10 11 12
  • substr(i, n): Returns a substring of length n starting at index i
    string greeting = "Hello, World!\n";
    string sub = greeting.substr(0, 4);
    cout << sub << endl;
    
  • string sub = greeting.substr(0, 4); // first 4 chars
    H e l l o , W o r l d !
    0 1 2 3 4 5 6 7 8 9 10 11 12
  • string w = greeting.substr(7, 5);
    H e l l o , W o r l d !
    0 1 2 3 4 5 6 7 8 9 10 11 12

Example Using String Functions

  • Consider the problem of extracting the initials from a person's name
  • What would be an algorithm for solving this problem?
  • To implement this algorithm, we can use the string function substr()
  • The following program implements an algorithm for extracting the initials from a person's name
  • Could we use the at() function to store characters in the string initials?

Program to Create Initials

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <string>
using namespace std;

int main() {
    string first;
    string middle;
    string last;
    cout << "Enter your full name (first middle last): ";
    cin >> first >> middle >> last;
    string initials = first.substr(0, 1)
        + middle.substr(0, 1) + last.substr(0, 1);
    cout << "Your initials are " << initials << "\n";

   return 0;
}

Extracting the Last Characters

  • Note that we can extract the last few letters of a string without knowing its length ahead of time
    string word;
    cout << "Enter a word: ";
    cin >> word;
    int lastLetter = word.size() - 1;
    cout << "The last letter of the word is "
         << word.substr(lastLetter) << endl;
    
  • If we call substr() with just the starting index, it returns the trailing characters
  • This technique can be adjusted to extract the last few characters instead of just one character

Common Errors

  • A common error is to access an invalid string index
  • Especially common is exactly one larger than the largest index
  • If a string word has 5 characters, the valid range of indexes are 0...4
  • Accessing with index 5 is an error
  • However, substr() will not notify you of a problem
  • Instead we may get bizarre program behavior

Check Yourself

  1. True or false: an object is a data type that can have functions associated with it.
  2. To call a function that is part of an object, between the object name and the function name we code a ________.
  3. The following code displays ________.
    string message = "Hi mom!";
    cout << message.length();
    
    1. 2
    2. 6
    3. 7
    4. 9
  4. string message = "Hi mom!";
    

    answer

  5. To print mom! the following substr() should be ________.
    string message = "Hi mom!";
    cout << message.substr(3, 5);
    
    1. substr(3, 5) // nothing is wrong
    2. substr(3, 4) // wrong ending character
    3. substr(4, 4) // wrong starting and ending chaaracter
    4. substr(4, 5) // wrong starting character

4.5.3: String Input With Spaces

  • We have been using the >> operator to enter data into a string variable:
    string something;
    cout << "Enter something: ";
    cin >> something;
    cout << "You entered: " << something << "END OF OUTPUT\n";
    
  • However, there are some complications
  • >> skips whitespace and stops on encountering more whitespace
  • Thus, we only get a single word for each input variable
  • If a user types in "Hello Mom!", we would only read "Hello" and not " Mom!"
  • This is because cin >> s1 works as follows:
    1. Skips whitespace
    2. Reads non-whitespace characters into the variable
    3. Stops reading when whitespace is found

Input Using getline()

  • To read an entire line we use function getline()
  • Syntax:
    getline(cin, stringVariable);
    
  • Where:
    • stringVariable: the name of the string variable
  • For example:
    string line;
    cout << "Enter a line of input:\n";
    getline(cin, line);
    cout << line << "END OF OUTPUT\n";
    
  • Note that getline() stops reading when it encounters a '\n'

The Problem with Newlines

  • When you press the Enter key, a newline character ('\n') is inserted as part of the input
  • The newline character can cause problems when you mix cin >> with getline()
  • Recall that cin >> s1:
    1. Skips whitespace
    2. Reads non-whitespace characters into the variable
    3. Stops reading when whitespace is found
  • Since whitespace includes newline characters, using cin >> will leave a newline character in the input stream
  • However, getline() just stops reading when it first finds a newline character
  • This can lead to mysterious results in code like the following:
    cout << "Enter your age: ";
    int age;
    cin >> age;
    cout << "Enter your full name: ";
    string name;
    getline(cin, name);
    cout << "Your age: " << age << endl
         << "Your full name: " << name << endl;
    
  • To correct this problem we use cin >> ws just before getline()
    cin >> ws; // clear whitespace from input stream
    
  • We can see how to use this fix in the following example

Example Using cin >> ws

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

int main() {
    cout << "Enter your age: ";
    int age;
    cin >> age;
    cout << "Enter your full name: ";
    string name;
    cin >> ws; // clear whitespace from buffer
    getline(cin, name);
    cout << "Your age: " << age << endl
         << "Your full name: " << name << endl;

    return 0;
}

Check Yourself

  1. True or false: Using the >> operator with string variables only reads one word at a time.
  2. To read strings containing multiple words use the ________ function.
  3. True or false: before you switch from using the >> operator to using getline(), you must clear the next newline character from the input buffer.
  4. To clear whitespace from the input buffer use: ________.
  5. The following code has a problem.
    1  int age;
    2  string name;
    3  cout << "Enter your age: ";
    4  cin >> age;
    5  cout << "Enter your full name: ";
    6  getline(cin, name);
    
    To fix the problem, we insert the following statement between lines ________.
    cin >> ws;
    
    1. 1 and 2
    2. 2 and 3
    3. 3 and 4
    4. 4 and 5

Exercise 4.5: Programming Strings (12m)

For this exercise we break into teams. Within the team, work with each other to develop a solution. When the team has finished, Choose one member to show your solution to the class by sharing your screen. The instructor will ask one team to share their solution.

In this exercise we write an interactive program using strings that runs like this:

First name: Ed
Last name: Parrish
Welcome "Ed Parrish"!
Your initials: EP

Note that the underlined font shows what is typed by the user. As you work through the exercise, I suggest that you compile after each step so you know where an error is located if you make a mistake. Also, if you get stuck then ask a classmate or the instructor for help.

Specifications

  1. Start Repl.it and copy the following program into a text editor.
    #include <iostream>
    using namespace std;
    
    int main() {
        // Enter your code here
    
        return 0;
    }
    
  2. In main(), declare three string variables, firstName, lastName, fullName, like this:
    string firstName, lastName, fullName;
    
  3. Add two statements: (1) to prompt the user for the data they should enter and (2) to collect the user input and store it in the firstName variable. For instance:
    cout << "First name: ";
    cin >> firstName;
    
  4. Add two more statements like these to collect the last name and store the input in the lastName variable.
  5. Write a line of code to concatenate (join) the first and last names and assign them to the variable fullName like this:
    fullName = firstName + " " + lastName;
    
  6. Finally, add code to your program to output the fullName variable using cout:
    cout << "Full name: " << fullName << "!\n";
    
  7. Compile and run your program to make sure it works correctly like this:
    First name: Ed
    Last name: Parrish
    Full name: Ed Parrish!
    
  8. Some text characters are hard to print, like a double quote ("). To print these we must escape them from their special meaning by putting a backslash (\) in front of them. Put a double quote mark around the full name by changing the line printing the full name to:
    cout << "Welcome \"" << fullName << "\"!\n";
    
  9. You can extract parts of a string variable using the substr() function. Extract the first letter from the first and last name to create initials with the following code:
    string initials = firstName.substr(0, 1)
        + lastName.substr(0, 1);
    cout << "Your initials: " << initials << endl;
    
  10. Compile and run your program to make sure it works correctly like this:
    First name: Ed
    Last name: Parrish
    Welcome "Ed Parrish"!
    Your initials: EP
    
  11. Once satisfied with your code, copy your code into a text editor, save the file as "nameapp.cpp", and submit the file to Canvas with the rest of the exercise files for the week.

When finished developing your code click hereClick to show answer to verify. Code need not look exactly the same. After you have completed your own program, reviewing another is often helpful in learning how to improve your programming skills.

4.6: Repetition (Loops)

Objectives

At the end of the lesson the student will be able to:

  • Use while statements to repeat sections of code
  • Discuss the usual parts of a loop
  • Describe what is meant by a main loop

4.6.1: Simple Loops

  • Sometimes we want to repeat a section of code
  • For instance, we may want to let a user run our program multiple times
  • When we want to repeat a section of code, we use a loop statement
  • A loop is a block of code that can execute repeatedly
  • Whether or not a program repeats a block of code is determined by a test condition
  • The test condition is checked each time through the loop

Mark Zuckerburg teaches Repeat Loops (1:31)

  • There are three general purpose loop statements in C++:
    • for
    • while
    • do...while
  • We will start with the simplest of the three -- the while statement

Check Yourself

  1. The purpose of a loop is to ________ a block of code.
  2. True or false: a test condition is checked each time a loop repeats.
  3. The three general purpose loops are: ________, ________ and ________.

4.6.2: Coding while Statements

  • The simplest looping structure is the while statement
  • A while statement has a test condition and a body, like an if statement
  • Before each execution of the loop body, the while statement checks the test condition
  • If the test condition evaluates to true, then our program executes the body of the loop
  • When the program reaches the end of the loop body, it automatically returns to the while statement
  • Syntax:
    while (test) {
       statement1
       statement2
       ...
    }
    
  • Where:
    • test: the test condition to evaluate
    • statementX: the statements to execute while the test remains true
  • For example:
    char repeat = 'y';
    while ('y' == repeat) {
        // ... statements to repeat
        cin >> repeat;
    }
    
  • The following flow chart shows how the while loop operates

Diagram of while Loop Operation

While loop syntax and flow chart

Check Yourself

  1. True or false: a while-loop includes an initialization statement as part of its syntax.
  2. A test condition must evaluate to ________ for a while loop to execute its body of statements.
  3. True or false: if the test condition of a while-loop evaluates to false, the statement after the while loop executes.

4.6.3: Understanding the while Loop

  • The following looping application simulates the play of an exciting game
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;

int main() {
    char repeat = 'y';
    while ('y' == repeat) {
        cout << "\nPlaying an exciting game!\n";
        cout << "Do you want to play again? (y/n) ";
        cin >> repeat;
    }
    cout << "\nThanks for playing!\n";

    return 0;
}
  • Notice the structure of the code for the looping application
  • First was the statement to correctly initialize the looping condition:
    char repeat = 'y';
    
  • Then came the while statement with the test condition
    while ('y' == repeat)
  • The loop executes the body of the loop if and only if the condition evaluates to true
  • Another important part of the loop is the statement:
    cin >> repeat;
  • Most loops have these parts:
    • Initialization code
    • Loop test condition
    • Loop body with some way to change the test condition
  • We will further explore the while loop in the next exercise

About those Curly Braces

  • Like the if-statement, the curly braces of a while loop are optional
  • Technically, the while statement affects only the single statement that follows
  • We use curly braces to make that one statement into a block of statements
  • This allows us to put any number of statements within the body
  • Curly braces are not always required, but the best practice is to always include them

Program Style: Indent Statements Inside a Loop

  • It is important to format the loop code correctly:
    char repeat = 'y';
    while ('y' == repeat) {
        // ... statements to repeat
        cin >> repeat;
    }
    
  • Note how the repeated code is indented inside the loop
  • This lets us see easily which code is repeated and which is not
  • Also note the placement of curly braces
  • Different groups have different practices for placing curly braces in a loop statement
  • For the acceptable styles for this course see: Curly Braces

Check Yourself

  1. True or false: if the test condition of a while loop evaluates to false the first time the loop is reached, it still executes one time.
  2. In the example code, which statement initializes the variable?
  3. True or false: the while-statement affects only a single statement unless curly braces are used.
  4. Which parts of a while-statement are indented?

Exercise 4.6: Repeating a Program (10m)

In this exercise we use a loop to allow a user to repeat a program.

For this exercise we break into teams. Within the team, work with each other to develop a solution. When the team has finished, Choose one member to show your solution to the class by sharing your screen. The instructor will ask one team to share their solution.

Specifications

  1. Start Repl.it and copy the following program into a text editor.
    #include <iostream>
    using namespace std;
    
    
    int main() {
        int guess = 0;
        cout << "I'm thinking of a number between"
             << " 1 and 10.\nCan you guess it?\n\n"
             << "Enter your guess: ";
        cin >> guess;
    
        if (7 == guess) {
            cout << "*** Correct! ***\n";
        } else {
            cout << "Sorry, that is not correct.\n";
            cout << "Try again.\n";
        }
        return 0;
    }
    
  2. Add the following code after the statement int guess = 0; and before the cout statement:
    char repeat = 'y';
    

    This is the initialization code that we will use for the test condition that comes next.

  3. We want to repeat all the rest of the code in our program. For this we need to add a while statement such as:
    while ('y' == repeat) {
        // Place the rest of the code after the initialization
        // and before the return 0 between these curly braces.
    }
    

    Statements inside the curly braces repeat while the test condition in the parenthesis, ('y' == repeat), evaluates to true. For more information, see section: 4.6.2: Coding while Statements.

  4. Inside the while loop we need some way to change the test condition. We change the test condition by letting the user enter a value for the repeat variable by adding the following code at the end of the loop just before the closing curly brace:
    cout << "\nDo you want to play again (y/n)? ";
    cin >> repeat;
    

    Without these two statements our loop would have no way to exit. A loop with no way to exit is known as an infinite loop. For more information, see section: 4.6.3: Understanding the while Loop.

  5. Formatting a loop is important. Indent all the code within the curly braces of the while loop. For more information, see Formatting the Code in the section: 4.6.3: Understanding the while Loop.
  6. As a final part of our program, we add the infamous phrase: "Game Over". Add the following statement after the closing curly brace of the while loop:
    cout << "Game over\n";
    
  7. Compile and run your program again and verify the output looks like:
    I'm thinking of a number between 1 and 10.
    Can you guess it?
    
    Enter your guess: 3
    Sorry, that is not correct.
    Try again.
    
    Do you want to play again (y/n)? y
    I'm thinking of a number between 1 and 10.
    Can you guess it?
    
    Enter your guess: 7
    *** Correct! ***
    
    Do you want to play again (y/n)? n
    Game over
    
  8. Once satisfied with your code, copy your code into a text editor, save the file as "loopy.cpp", and submit the file to Canvas with the rest of the exercise files for the week.

When finished developing your code click hereClick to show answer to verify. Code need not look exactly the same. After you have completed your own program, reviewing another is often helpful in learning how to improve your programming skills.

As time permits, read the following sections and be prepared to answer the Check Yourself questions in the section: 4.6.5: Summary.

Image
Image source

4.6.4: Common Loop Pitfalls

  • Loops have many pitfalls for the unwary
  • The following are the most common problems to look out for and avoid

Infinite Loops

  • Common error: unintentional infinite loop
  • For example, what is wrong with the following code?
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;

int main() {
    string repeat = "y";
    while ("y" == repeat) {
        cout << "\nPlaying an exciting game!\n";
        cout << "Do you want to play again? (y/n) ";
    }
    cout << "\nThanks for playing!\n";

    return 0;
}

Missing Curly Braces

  • Technically, the while loop executes a single statement after the parenthesis of the test condition
  • However, we usually use curly braces { } to expand the single statement
  • The curly braces let us put multiple statements in them
  • For example, what is wrong with the following code?
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;

int main() {
    string repeat = "y";
    while ("y" == repeat)
        cout << "\nPlaying an exciting game!\n";
        cout << "Do you want to play again? (y/n) ";
        cin >> repeat;
    cout << "\nThanks for playing!\n";

    return 0;
}

Empty Statements

  • Remember that statements are terminated by a semicolon
  • Is the following a legal statement?
    ;
  • This is known as an empty or null statement
  • Empty statements are a common source of infinite loops
  • For example, what is wrong with the following code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;

int main() {
    string repeat = "y";
    while ("y" == repeat); {
        cout << "\nPlaying an exciting game!\n";
        cout << "Do you want to play again? (y/n) ";
        cin >> repeat;
    }
    cout << "\nThanks for playing!\n";

    return 0;
}

Check Yourself

  1. What is the output from the following loop:
    int i = 10;
    while (i <= 10) {
       cout << i << " ";
    }
    
  2. How many times is the following loop executed?
    int counter = 1;
    while (counter > 20) {
       counter = counter + 1;
    }
    
  3. What is wrong with the following code?
    char repeat = 'y';
    while ('y' == repeat); {
        cout << "Do you want to run again? (y/n) ";
        // ... statements to execute
        cin >> repeat;
    }
    
Last Updated: March 10 2021 @21:31:52