Tutorial

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.


SERIES

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.

Table of Contents

C-style arrays

A C-style array stores a fixed number of elements of the same type in contiguous memory:

C++
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:

C++
std::cout << scores[0];   // 85  (first)
std::cout << scores[4];   // 88  (last)
scores[2] = 100;          // change third element

Iterating a C-style array

C++
int n = 5;
for (int i = 0; i < n; i++) {
    std::cout << scores[i] << " ";
}

The fundamental danger: out-of-bounds access

C++
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

C++
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:

C++
#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:

C++
#include <vector>

std::vector<int> nums;             // empty vector of ints
std::vector<int> primes = {2, 3, 5, 7, 11};

Adding and removing elements

C++
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

C++
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

C++
// 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

C++
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>

C++
#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:

C++
#include <string>

std::string name = "Alice";
std::string greeting = "Hello, " + name + "!";
std::cout << greeting;  // Hello, Alice!

Common string methods

C++
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:

C++
#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

C++
// 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

C++
#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::array is the safe alternative for fixed-size collections.
  • std::vector is your go-to container: dynamic, safe with .at(), and works with all standard algorithms.
  • std::string handles text naturally; use std::to_string / std::stoi to convert.
  • Include <algorithm> for sort, find, max, min, and dozens of other utilities.

Next up: pointers and memory management — the feature that makes C++ both powerful and challenging.


Was this article helpful?

w

webencher Editorial

Software engineers and technical writers with 10+ years of combined experience in algorithms, systems design, and web development. Every article is reviewed for accuracy, depth, and practical applicability.

More by this author →