Week 3: Interaction & Basic Decisions
Learn how to interact with users and guide your program's flow using conditionals.
Explore Chapter 3Chapter 3: Input/Output and Conditional Control Flow
Standard Input/Output (`iostream`).
To make programs interactive, we need ways to display information to the user and receive input from them. In C++, the standard way to do this is using the `iostream` library.
You need to include the header file at the beginning of your code:
#include <iostream>
Output with `std::cout`
The `std::cout` object (stands for "character output") is used with the insertion operator (`<<`) to send data to the standard output stream (usually the console).
int score = 95;
std::string name = "Alice";
std::cout << "Hello, World!" << std::endl; // std::endl inserts a newline and flushes the buffer
std::cout << "Name: " << name << ", Score: " << score << '\n'; // '\n' also inserts a newline
You can chain multiple `<<` operators to output various data types.
Input with `std::cin`
The `std::cin` object (stands for "character input") is used with the extraction operator (`>>`) to read data from the standard input stream (usually the keyboard).
int age;
std::string username;
std::cout << "Enter your age: ";
std::cin >> age; // Reads an integer from input
std::cout << "Enter your username: ";
std::cin >> username; // Reads a string (stops at whitespace)
std::cout << "Welcome, " << username << "! You are " << age << " years old." << std::endl;
Input Issues & `getline`
The `>>` operator stops reading at the first whitespace character (space, tab, newline). This can be problematic when reading strings with spaces. To read an entire line of text, use the `std::getline()` function.
#include <string> // Need to include the string header
// ... include iostream too ...
std::string fullName;
std::cout << "Enter your full name: ";
// std::cin.ignore(); // May be needed after using cin >> age; to consume leftover newline
std::getline(std::cin, fullName); // Reads the entire line
std::cout << "Your full name is: " << fullName << std::endl;
Handling input robustly (checking for valid types, dealing with errors) is an important aspect we'll revisit.
Control Flow - Conditional Statements (`if`, `else if`, `else`).
Conditional statements allow your program to execute different blocks of code based on whether a condition is true or false.
`if` Statement
Executes a block of code only if the condition is true.
int temperature = 25;
if (temperature > 20) {
std::cout << "It's a warm day!" << std::endl;
}
`if...else` Statement
Executes one block if the condition is true and another block if it's false.
int number = 7;
if (number % 2 == 0) {
std::cout << "The number is even." << std::endl;
} else {
std::cout << "The number is odd." << std::endl;
}
`if...else if...else` Statement
Allows checking multiple conditions in sequence.
int grade = 85;
if (grade >= 90) {
std::cout << "Grade: A" << std::endl;
} else if (grade >= 80) {
std::cout << "Grade: B" << std::endl; // This block executes
} else if (grade >= 70) {
std::cout << "Grade: C" << std::endl;
} else {
std::cout << "Grade: D or F" << std::endl;
}
Conditions are evaluated using comparison (`==`, `!=`, `>`, `<`, `>=`, `<=`) and logical (`&&`, `||`, `!`) operators.
Nested `if` Statements.
You can place `if`, `else if`, or `else` statements inside the block of another conditional statement. This allows for more complex decision-making logic.
int age = 20;
bool hasLicense = true;
if (age >= 18) {
std::cout << "Eligible age." << std::endl;
if (hasLicense) {
std::cout << "Can drive." << std::endl;
} else {
std::cout << "Cannot drive without a license." << std::endl;
}
} else {
std::cout << "Not eligible age to drive." << std::endl;
}
While powerful, excessive nesting can make code difficult to read and debug. Consider alternative structures or breaking logic into functions if nesting becomes too deep.
The `switch` Statement.
The `switch` statement provides an alternative way to execute different blocks of code based on the value of an expression, specifically when comparing against multiple constant integer or character values.
Syntax
switch (expression) {
case constant1:
// Code block for constant1
break; // Important: Exits the switch
case constant2:
// Code block for constant2
break;
// ... more cases
default:
// Code block if no case matches (optional)
break; // Technically optional here, but good practice
}
- The `expression` must evaluate to an integer type (`int`, `char`, `enum`).
- Each `case` label is followed by a constant value and a colon `:`.
- Execution jumps to the matching `case` label.
- The `break` statement is crucial! Without it, execution will "fall through" to the next case, which is usually unintended.
- The `default` case is optional and executes if no other case matches.
Example
char grade = 'B';
switch (grade) {
case 'A':
std::cout << "Excellent!" << std::endl;
break;
case 'B':
std::cout << "Very Good!" << std::endl;
break;
case 'C':
std::cout << "Good." << std::endl;
break;
default:
std::cout << "Needs Improvement." << std::endl;
break;
}
`switch` statements can be clearer than long `if-else if` chains when dealing with multiple specific constant values.