C++ for Beginners Part 5: Arrays, Strings, and std::vector
Work with collections of data in C++. Covers C-style arrays and their pitfalls, std::array for fixed-size collections, std::string and its most useful methods, and std::vector — the dynamically resizable container you'll use in almost every program.
C++ for Beginners: A Complete Guide
An eight-part beginner-friendly journey through C++: from writing your first program and understanding variables, through control flow, functions, and arrays, to the heart of C++ — pointers, classes, inheritance, and polymorphism. Each article is self-contained and builds on the previous, giving you both a quick reference and a progressive path to mastery.
- 3 C++ for Beginners Part 3: Control Flow — Conditions and Loops
- 4 C++ for Beginners Part 4: Functions
- 5 C++ for Beginners Part 5: Arrays, Strings, and std::vector
- 6 C++ for Beginners Part 6: Pointers and Memory Management
- 7 C++ for Beginners Part 7: Classes and Object-Oriented Programming
Table of Contents
- C-style arrays
- Iterating a C-style array
- The fundamental danger: out-of-bounds access
- Multidimensional arrays
- std::array — safer fixed-size arrays (C++11)
- std::vector — the container you'll use most
- Adding and removing elements
- Accessing elements
- Iterating
- Useful vector operations
- Sorting and searching with <algorithm>
- std::string
- Common string methods
- Splitting strings
- Converting between strings and numbers
- Practical example: word frequency counter
- Key takeaways
C-style arrays
A C-style array stores a fixed number of elements of the same type in contiguous memory:
int scores[5]; // 5 integers, uninitialised — don't do this
int scores[5] = {85, 92, 78, 96, 88}; // initialise all five
int scores[] = {85, 92, 78, 96, 88}; // size inferred (5)
Access elements by zero-based index:
std::cout << scores[0]; // 85 (first)
std::cout << scores[4]; // 88 (last)
scores[2] = 100; // change third element
Iterating a C-style array
int n = 5;
for (int i = 0; i < n; i++) {
std::cout << scores[i] << " ";
}
The fundamental danger: out-of-bounds access
int arr[3] = {10, 20, 30};
std::cout << arr[5]; // undefined behaviour — reads garbage or crashes
C++ does not check array bounds at runtime. Accessing outside the array is undefined behaviour — one of the most common sources of security vulnerabilities and crashes.
Multidimensional arrays
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
};
std::cout << matrix[1][2]; // 7
std::array — safer fixed-size arrays (C++11)
std::array is a thin wrapper around a C-style array that knows its own size and works with standard algorithms:
#include <array>
std::array<int, 5> scores = {85, 92, 78, 96, 88};
std::cout << scores.size(); // 5
std::cout << scores.at(10); // throws std::out_of_range (bounds checked!)
std::cout << scores.front(); // 85
std::cout << scores.back(); // 88
for (int s : scores) {
std::cout << s << " ";
}
Prefer std::array over C-style arrays for fixed-size collections.
std::vector — the container you'll use most
std::vector is a dynamically resizable array. You don't need to know the size ahead of time:
#include <vector>
std::vector<int> nums; // empty vector of ints
std::vector<int> primes = {2, 3, 5, 7, 11};
Adding and removing elements
std::vector<std::string> names;
names.push_back("Alice"); // add to end
names.push_back("Bob");
names.push_back("Charlie");
names.pop_back(); // remove last element
std::cout << names.size(); // 2
Accessing elements
std::cout << names[0]; // "Alice" (no bounds check)
std::cout << names.at(1); // "Bob" (throws if out of range)
std::cout << names.front(); // "Alice"
std::cout << names.back(); // "Bob"
Iterating
// Range-based for (preferred)
for (const std::string& name : names) {
std::cout << name << "
";
}
// Index-based
for (size_t i = 0; i < names.size(); i++) {
std::cout << i << ": " << names[i] << "
";
}
Use const std::string& to avoid copying each element.
Useful vector operations
std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};
// Size and capacity
v.size(); // 8
v.empty(); // false
v.clear(); // remove all elements
// Insert at position 2
v.insert(v.begin() + 2, 99);
// Remove element at position 2
v.erase(v.begin() + 2);
// Reserve space (avoids reallocations when you know approximate size)
v.reserve(100);
Sorting and searching with <algorithm>
#include <algorithm>
std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};
std::sort(v.begin(), v.end()); // ascending
// v = {1, 1, 2, 3, 4, 5, 6, 9}
std::sort(v.begin(), v.end(), std::greater<int>()); // descending
// v = {9, 6, 5, 4, 3, 2, 1, 1}
auto it = std::find(v.begin(), v.end(), 5);
if (it != v.end()) {
std::cout << "Found 5 at index " << (it - v.begin()) << "
";
}
std::string
std::string is the standard C++ string type. Prefer it over C-style char arrays:
#include <string>
std::string name = "Alice";
std::string greeting = "Hello, " + name + "!";
std::cout << greeting; // Hello, Alice!
Common string methods
std::string s = "Hello, World!";
s.length(); // 13
s.size(); // 13 (same as length)
s.empty(); // false
s[0]; // 'H'
s.at(0); // 'H' (bounds-checked)
s.front(); // 'H'
s.back(); // '!'
s.substr(7, 5); // "World" (start index, length)
s.find("World"); // 7 (returns position, or string::npos if not found)
s.find("xyz"); // string::npos
s.replace(7, 5, "C++"); // "Hello, C++!"
// Append
s += " Goodbye.";
s.append(" See you.");
// Case — no built-in, use <algorithm>
#include <algorithm>
#include <cctype>
std::string upper = s;
std::transform(upper.begin(), upper.end(), upper.begin(), ::toupper);
Splitting strings
C++ doesn't have a built-in split, but you can use std::istringstream:
#include <sstream>
#include <vector>
std::string csv = "apple,banana,cherry";
std::istringstream stream(csv);
std::string token;
std::vector<std::string> parts;
while (std::getline(stream, token, ',')) {
parts.push_back(token);
}
// parts = {"apple", "banana", "cherry"}
Converting between strings and numbers
// Number to string
std::string s = std::to_string(42); // "42"
std::string f = std::to_string(3.14); // "3.140000"
// String to number
int n = std::stoi("123"); // 123
double d = std::stod("3.14"); // 3.14
long l = std::stol("9876543210");
Practical example: word frequency counter
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
int main() {
std::string line;
std::cout << "Enter a sentence: ";
std::getline(std::cin, line);
std::istringstream stream(line);
std::string word;
std::map<std::string, int> freq;
while (stream >> word) {
freq[word]++;
}
for (const auto& [w, count] : freq) {
std::cout << w << ": " << count << "
";
}
}
// Input: the cat sat on the mat the cat
// Output: cat: 2 mat: 1 on: 1 sat: 1 the: 3
We introduced std::map here — a key-value container covered in depth later. For now, note that freq[word]++ starts the count at 0 automatically.
Key takeaways
- C-style arrays are fixed-size and do not check bounds — dangerous for beginners.
std::arrayis the safe alternative for fixed-size collections.std::vectoris your go-to container: dynamic, safe with.at(), and works with all standard algorithms.std::stringhandles text naturally; usestd::to_string/std::stoito convert.- Include
<algorithm>forsort,find,max,min, and dozens of other utilities.
Next up: pointers and memory management — the feature that makes C++ both powerful and challenging.