Lessons learned from a Simple C++ Capitalisation Function
Original Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <iostream> #include <string>
using namespace std;
string capitalise(string raw){ if(raw[0] >= 'a' && raw[0] <= "z"){ raw[0] += ('A' - 'a'); } string capitalised = raw; return capitalised; }
int main(){ cout << "Please input string: " << endl; string rawString = ""; rawString += cin; cout << endl; rawString = capitalise(rawString); cout << rawString << endl; return 0; }
|
Character vs. String Literals ('z' vs "z")
Error:
1
| if (raw[0] >= 'a' && raw[0] <= "z")
|
Lesson:
'z' is a character literal (type char).
"z" is a string literal (type const char*, a null-terminated array).
- I can’t compare a
char (raw[0]) with a const char* ("z").
- Fix: Always use single quotes (
' ') for characters and double quotes (" ") for strings.
Correct Way:
1
| if (raw[0] >= 'a' && raw[0] <= 'z')
|
Error:
Lesson:
cin is an input stream (istream), not a string.
- Operator
+= does not work with streams.
- Ways to read input:
cin >> str (reads until whitespace, not full lines).
getline(cin, str) (reads entire line, including spaces).
Correct Way:
1 2
| string rawString; getline(cin, rawString);
|
Handling Empty Strings Safely
Error:
Original code did not check if raw was empty before accessing raw[0].
Lesson:
- Accessing
raw[0] on an empty string is undefined behavior.
- Always check
!str.empty() before accessing str[0].
Correct Way:
1 2 3
| if (!raw.empty() && raw[0] >= 'a' && raw[0] <= 'z') { raw[0] += ('A' - 'a'); }
|
Avoiding Unnecessary Copies
Original Code:
1 2
| string capitalised = raw; return capitalised;
|
Lesson:
- Copying strings is inefficient (especially for long strings).
- Return the modified string directly (C++ optimizes this via Return Value Optimization (RVO)).
Optimized Way:
Understanding C++ Streams (cin, cout)
Error:
Trying to use cin as if it were a string.
Lesson:
cin is an input stream (istream), not a string.
Use >> for word-by-word input or getline() for full-line input.
Example:
1 2 3 4 5
| int num; cin >> num;
string line; getline(cin, line);
|
Compiler Warnings
What the Compiler Told Me:
- “Comparison between pointer and integer” → I compared
char with const char*.
- “No viable overloaded ‘+=’” → I tried to add
cin to a string.
Final Corrected Code (Recap)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include <iostream> #include <string>
using namespace std;
string capitalise(string raw) { if (!raw.empty() && raw[0] >= 'a' && raw[0] <= 'z') { raw[0] += ('A' - 'a'); } return raw; }
int main() { cout << "Please input string: " << endl; string rawString; getline(cin, rawString); rawString = capitalise(rawString); cout << rawString << endl; return 0; }
|
Key Takeaways for Future Code:
| Mistake |
Lesson |
raw[0] <= "z" |
Use 'z' for chars, "z" for strings. |
rawString += cin |
Use getline(cin, str) to read input. |
| No empty check |
Always check !str.empty() before str[0]. |
| Unnecessary copy |
Return the string directly (RVO optimises it). |
Misusing cin |
cin is a stream, not a string. Use >> or getline(). |
- Be careful with string literals and char literals.
"s" vs 's'
- Don’t treat
cin as if it was a std::string type variable.
- Always check for empty strings before accessing elements.
- Avoid unnecessary copies (let C++ optimise).
- Learn more about
getline() function and enhance the understanding stream.