Skip to content

Commit 60f70b3

Browse files
committed
Add 02-core modules: input validation and algorithms basics
1 parent 7eb2de9 commit 60f70b3

12 files changed

Lines changed: 414 additions & 11 deletions

File tree

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@ Current C++ foundations modules:
3232
- `control-flow`
3333
- `functions`
3434
- `arrays-and-vectors`
35+
- `strings`
3536

36-
Next C++ module:
37+
Current C++ core modules:
3738

38-
- `01-foundations/strings`
39+
- `02-core/input-validation`
40+
- `02-core/algorithms-basics`
3941

4042
## Guided Learning Path
4143

@@ -45,7 +47,7 @@ Next C++ module:
4547
- read `README.md`
4648
- run `example/main.cpp`
4749
- solve `exercises/01.cpp` and `exercises/02.cpp`
48-
- for strings, continue with `languages/cpp/01-foundations/strings`
50+
- after foundations, continue with `languages/cpp/02-core`
4951
4. Mark progress in `languages/cpp/CHECKLIST.md`
5052
5. Repeat until all modules are complete
5153

languages/cpp/02-core/README.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
# 02 Core
22

3-
This level is reserved for intermediate C++ topics that build on foundations.
3+
This level introduces intermediate patterns that build directly on foundations.
44

5-
## Intended Topics
5+
## Module Order
66

7-
- Strings in depth and parsing patterns
8-
- Standard library containers and algorithms
9-
- Error handling basics
7+
1. [input-validation](./input-validation/README.md)
8+
2. [algorithms-basics](./algorithms-basics/README.md)
109

11-
## Status
10+
## How To Study This Level
1211

13-
This level folder is ready for future modules.
12+
For each module:
13+
14+
1. Read `README.md`.
15+
2. Run `example/main.cpp`.
16+
3. Complete `exercises/01.cpp` and `exercises/02.cpp`.
17+
4. Mark progress in `../CHECKLIST.md`.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Algorithms Basics
2+
3+
This module introduces essential algorithmic patterns using loops and vectors.
4+
5+
## Why It Matters
6+
7+
Many programming problems reduce to a few patterns: search, count, and min/max scanning.
8+
9+
## Quick Run
10+
11+
```bash
12+
g++ -std=c++17 -Wall -Wextra -pedantic example/main.cpp -o algorithms_basics_example
13+
./algorithms_basics_example
14+
```
15+
16+
On Windows (MSYS2 shell), run:
17+
18+
```bash
19+
./algorithms_basics_example.exe
20+
```
21+
22+
## Topics Covered
23+
24+
### Linear Search
25+
26+
Find the first position of a target by scanning from left to right.
27+
28+
### Counting Pattern
29+
30+
Count how many values match a condition (for example, equal to a target).
31+
32+
### Min/Max Scan
33+
34+
Track smallest and largest values while iterating once through data.
35+
36+
## Common Pitfalls
37+
38+
- Forgetting to handle empty input.
39+
- Using uninitialized `min`/`max` values.
40+
- Doing extra loops when one pass is enough.
41+
42+
## Exercise Focus
43+
44+
- `exercises/01.cpp`: implement linear search over user-provided values.
45+
- `exercises/02.cpp`: compute min, max, and count of even numbers in one pass.
46+
47+
## Checkpoint
48+
49+
- [ ] I can implement linear search.
50+
- [ ] I can count values matching a condition.
51+
- [ ] I can compute min and max safely.
52+
- [ ] I completed both exercises.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include <iostream>
2+
#include <vector>
3+
4+
int linearSearch(const std::vector<int>& values, int target) {
5+
for (std::size_t i = 0; i < values.size(); ++i) {
6+
if (values[i] == target) {
7+
return static_cast<int>(i);
8+
}
9+
}
10+
return -1;
11+
}
12+
13+
int countOccurrences(const std::vector<int>& values, int target) {
14+
int count = 0;
15+
for (int value : values) {
16+
if (value == target) {
17+
++count;
18+
}
19+
}
20+
return count;
21+
}
22+
23+
void printMinMax(const std::vector<int>& values) {
24+
if (values.empty()) {
25+
std::cout << "No values to process.\n";
26+
return;
27+
}
28+
29+
int minValue = values[0];
30+
int maxValue = values[0];
31+
for (int value : values) {
32+
if (value < minValue) {
33+
minValue = value;
34+
}
35+
if (value > maxValue) {
36+
maxValue = value;
37+
}
38+
}
39+
40+
std::cout << "Minimum: " << minValue << '\n';
41+
std::cout << "Maximum: " << maxValue << '\n';
42+
}
43+
44+
int main() {
45+
const std::vector<int> values{4, 7, 4, 1, 9, 4, 2};
46+
const int target = 4;
47+
48+
const int firstIndex = linearSearch(values, target);
49+
std::cout << "First index of " << target << ": " << firstIndex << '\n';
50+
std::cout << "Occurrences of " << target << ": " << countOccurrences(values, target) << '\n';
51+
52+
printMinMax(values);
53+
return 0;
54+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <iostream>
2+
#include <vector>
3+
4+
int main() {
5+
int n = 0;
6+
std::cout << "How many integers? ";
7+
std::cin >> n;
8+
9+
if (n <= 0) {
10+
std::cout << "Please enter a positive count.\n";
11+
return 0;
12+
}
13+
14+
std::vector<int> values;
15+
values.reserve(static_cast<std::size_t>(n));
16+
17+
for (int i = 0; i < n; ++i) {
18+
int value = 0;
19+
std::cout << "Value " << (i + 1) << ": ";
20+
std::cin >> value;
21+
values.push_back(value);
22+
}
23+
24+
int target = 0;
25+
std::cout << "Target to find: ";
26+
std::cin >> target;
27+
28+
int index = -1;
29+
for (int i = 0; i < n; ++i) {
30+
if (values[static_cast<std::size_t>(i)] == target) {
31+
index = i;
32+
break;
33+
}
34+
}
35+
36+
std::cout << "First index: " << index << '\n';
37+
return 0;
38+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include <iostream>
2+
#include <vector>
3+
4+
int main() {
5+
int n = 0;
6+
std::cout << "How many integers? ";
7+
std::cin >> n;
8+
9+
if (n <= 0) {
10+
std::cout << "Please enter a positive count.\n";
11+
return 0;
12+
}
13+
14+
std::vector<int> values;
15+
values.reserve(static_cast<std::size_t>(n));
16+
17+
for (int i = 0; i < n; ++i) {
18+
int value = 0;
19+
std::cout << "Value " << (i + 1) << ": ";
20+
std::cin >> value;
21+
values.push_back(value);
22+
}
23+
24+
int minValue = values[0];
25+
int maxValue = values[0];
26+
int evenCount = 0;
27+
28+
for (int value : values) {
29+
if (value < minValue) {
30+
minValue = value;
31+
}
32+
if (value > maxValue) {
33+
maxValue = value;
34+
}
35+
if (value % 2 == 0) {
36+
++evenCount;
37+
}
38+
}
39+
40+
std::cout << "Minimum: " << minValue << '\n';
41+
std::cout << "Maximum: " << maxValue << '\n';
42+
std::cout << "Even numbers: " << evenCount << '\n';
43+
return 0;
44+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Input Validation
2+
3+
This module teaches how to read user input safely and repeatedly until it is valid.
4+
5+
## Why It Matters
6+
7+
Real programs must handle invalid input without crashing or producing wrong results.
8+
9+
## Quick Run
10+
11+
```bash
12+
g++ -std=c++17 -Wall -Wextra -pedantic example/main.cpp -o input_validation_example
13+
./input_validation_example
14+
```
15+
16+
On Windows (MSYS2 shell), run:
17+
18+
```bash
19+
./input_validation_example.exe
20+
```
21+
22+
## Topics Covered
23+
24+
### Stream Validation
25+
26+
- `std::cin >> value` can fail when input type is wrong.
27+
- On failure, clear error state with `std::cin.clear()`.
28+
- Remove bad input with `std::cin.ignore(...)`.
29+
30+
### Range Validation
31+
32+
- Validate business rules after extraction (for example, age must be between 1 and 120).
33+
- Keep asking until the value is acceptable.
34+
35+
### Reusable Validation Functions
36+
37+
Use small helper functions to avoid repeating validation logic.
38+
39+
## Common Pitfalls
40+
41+
- Not clearing `std::cin` after invalid input.
42+
- Accepting values outside expected ranges.
43+
- Writing duplicate validation loops everywhere instead of reusable helpers.
44+
45+
## Exercise Focus
46+
47+
- `exercises/01.cpp`: read a valid integer in a range and print its square.
48+
- `exercises/02.cpp`: read multiple valid scores and compute class average.
49+
50+
## Checkpoint
51+
52+
- [ ] I can detect extraction failure and recover safely.
53+
- [ ] I can enforce numeric ranges.
54+
- [ ] I can loop until valid data is entered.
55+
- [ ] I completed both exercises.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#include <iostream>
2+
#include <limits>
3+
#include <string>
4+
5+
int readIntInRange(const std::string& label, int minValue, int maxValue) {
6+
int value = 0;
7+
8+
while (true) {
9+
std::cout << label;
10+
if (!(std::cin >> value)) {
11+
std::cout << "Invalid input type. Please enter an integer.\n";
12+
std::cin.clear();
13+
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
14+
continue;
15+
}
16+
17+
if (value < minValue || value > maxValue) {
18+
std::cout << "Value must be between " << minValue << " and " << maxValue << ".\n";
19+
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
20+
continue;
21+
}
22+
23+
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
24+
return value;
25+
}
26+
}
27+
28+
double readDoubleInRange(const std::string& label, double minValue, double maxValue) {
29+
double value = 0.0;
30+
31+
while (true) {
32+
std::cout << label;
33+
if (!(std::cin >> value)) {
34+
std::cout << "Invalid input type. Please enter a decimal number.\n";
35+
std::cin.clear();
36+
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
37+
continue;
38+
}
39+
40+
if (value < minValue || value > maxValue) {
41+
std::cout << "Value must be between " << minValue << " and " << maxValue << ".\n";
42+
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
43+
continue;
44+
}
45+
46+
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
47+
return value;
48+
}
49+
}
50+
51+
int main() {
52+
const int age = readIntInRange("Enter your age (1-120): ", 1, 120);
53+
const double gpa = readDoubleInRange("Enter your GPA (0.0-4.0): ", 0.0, 4.0);
54+
55+
std::cout << "\nValidated input summary:\n";
56+
std::cout << "Age: " << age << '\n';
57+
std::cout << "GPA: " << gpa << '\n';
58+
59+
return 0;
60+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <iostream>
2+
#include <limits>
3+
4+
int main() {
5+
int value = 0;
6+
7+
while (true) {
8+
std::cout << "Enter an integer from 1 to 100: ";
9+
if (!(std::cin >> value)) {
10+
std::cout << "Invalid input. Please enter an integer.\n";
11+
std::cin.clear();
12+
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
13+
continue;
14+
}
15+
16+
if (value < 1 || value > 100) {
17+
std::cout << "Out of range. Try again.\n";
18+
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
19+
continue;
20+
}
21+
22+
break;
23+
}
24+
25+
std::cout << "Square: " << (value * value) << '\n';
26+
return 0;
27+
}

0 commit comments

Comments
 (0)