The String Class Toolkit, Explained with Code Examples

UPI Study › Courses › C++ Programming › Free lessons › Lesson 7.4 Free with a free account

The String Class Toolkit

C++ Programming · Chapter 7: Text and Applied CollectionsSection 7.4 · lesson 46 of 84video coming soon

← Assembling and Editing String ContentNext lesson: Presenting Text Precisely →

Earn 3 college credits for C++ ProgrammingRecommended for credit by NCCRS · Computer Science 242 · self-paced · one payment, lifetime access

In this lesson

Properties, methods, and practical usage.

  • Explain value semantics: copying, assigning, comparing
  • Tell size from capacity, and know when storage moves
  • Read iterator code: what begin() and end() mean
  • Pass and return strings without needless copies

Transcript

Everything said in the video, section by section (1,435 words). Read along, or search it.

Big Picture

What Kind of Thing Is a String

You've been using std::string operation by operation. This lesson steps back and asks what kind of thing it is. Almost everything about how it behaves, what it costs, and how it should be passed around follows from a single fact: it's an object that owns its own storage, and behaves like a value.

Core Concept

Value Semantics Versus Raw Pointers

A std::string holds its own characters. It isn't a pointer to text living elsewhere. This is called value semantics: a string behaves the way int does, rather than the way a raw array does. A holds Bhopal. B equals a makes b an independent copy. Setting b to Indore changes b only. A is still Bhopal. And comparing a with Bhopal compares the text, not addresses. Now two char pointers, aimed at two separate arrays that both spell Bhopal. P equals equals q asks about the arrows, not the text, and says no. After a string copy, the two strings share nothing. With pointers, it's one set of characters with two names, or two sets that merely look alike.

Benefits and Cost

What Value Semantics Buys You

Here's what value semantics buys you. A copy of a string is independent. With an array, assignment isn't allowed at all, and with a pointer, it copies the arrow, not the text. Equals-equals is true when the text matches, and less-than gives dictionary order, rather than comparing addresses. Passed by value, a function gets its own copy. And returning a string from a function is safe. Returning a local array's address is a serious fault. The trade is that copies are real. Assigning or passing a long string by value copies every character. That isn't a reason to avoid strings. It's the reason for const references, coming shortly.

Sub-Topic

Size Versus Capacity in Growth

Two different numbers describe how much room a string is using. Size is how many characters it currently holds. Capacity is how many it could hold before it must find somewhere bigger. Capacity is always at least as large as size, and usually larger. Watch a real string grow, one character at a time. It starts empty, with room to spare. Whenever the capacity changes, the program prints the size at that moment. Append one character past capacity, and a larger block is obtained, every character is moved into it, and the old block is released. The exact numbers depend on the library. When you already know roughly how long the result will be, reserve asks for that capacity up front, and removes the moves altogether.

Common Mistake

Reallocation Invalidates Held Positions

Reallocation isn't free, but it's rarer than it looks. Capacity grows by a multiplying factor, rather than by one, so a move happens only occasionally, and the average cost per character stays small. But there's a consequence that catches people. When a string reallocates, its characters physically move. Anything that was pointing into the old block, a pointer, a reference to a character, or an iterator, now refers to memory that's been released. Using it afterward is undefined behavior. It might print the right letter, or garbage, or crash, and the symptom often appears far from the cause. So the rule is simple. Don't hold on to a position inside a string across any operation that might change its length.

Comparison

Brackets Versus At for Indexing

Square brackets and at both reach a character by index. They differ over exactly one thing: what happens when the index is wrong. Square brackets don't check. They read or write whatever is there, and the behavior is undefined. At checks, and throws an out of range exception, which can be caught and reported. The check costs one comparison per access. The sensible default is brackets inside loops you've written and bounded yourself, and at whenever the index has any other origin: input, a calculation, or a file. One precise detail. The position equal to the size is defined, and yields the null character. That's how a string can hand its contents to C-style interfaces. At, with the same index, throws, as it should.

Definition

Iterators and the Half-Open Range

An iterator is a position within a sequence. Begin gives the position of the first character. End gives the position one past the last, not the last character itself. Together they mark a half-open range: the first character, and one step past the final one. End is a stopping marker, and it's never dereferenced. It's the same idea as indexes running from zero to size minus one. That's why an iterator loop stops on not-equal to end, rather than on less-than-or-equal to something. So there are three ways of walking a string, and they do the same work. An index loop, when the position number is needed. An iterator loop, when working with library operations that take positions. And the range-based loop, for everyday reading: the shortest, the clearest, and it can't go out of range. Iterators aren't a string idea at all. A vector has begin and end, meaning exactly the same thing, and so does every other standard container. Learning the convention once buys you the whole library.

Worked Example

Choosing How to Pass Strings

Because a string owns its characters, passing one by value copies all of them. For a parameter the function only reads, that copy is pure waste. The fix is a reference marked const, which gives access without a copy, and without permission to modify. Report takes a const reference: it reads only. Shout takes a plain reference, because it modifies the caller's string. Tag takes its own copy by value, which is honest only if it needs one. And join parts returns a new string by value. Returning by value is correct, and efficient in practice. Run it to see each effect. Report prints the name. Shout changes the caller's string, adding an exclamation mark. Tag's star lands only on its own copy, so n never gets one.

Absolute Rule

Never Return a Local Reference

One rule here is absolute. Never return a reference to a local string. A local string ceases to exist when the function ends. Returning a reference to one hands back a reference to something that's gone, and the caller reads memory that's been reused. The compiler can spot this one and warns. Return by value instead. It's safe, and it isn't the performance problem it looks like.

Application

Strings Inside Containers and Loops

Strings are ordinary values, so they sit inside containers exactly as numbers do. An array of seven strings holds the days of the week. A vector of strings grows with push back, adding Rahul, then Priya. And notice the parameter form appearing again, in the range-based loop. Writing for string n in names copies every string once per pass. Writing const string reference doesn't. The same reasoning that governs function parameters governs loop variables, because it's the same question: does this need its own copy?

Reference List

Member Functions Grouped by Purpose

Here's a reference, consolidated for lookup, rather than for reading through. Size and storage: size, length, empty, capacity, reserve, and clear. Access: brackets, at, front, back, begin and end. Searching: find, r find, and find first of. Extracting and building: sub S T R, plus, append, and push back. Modifying: insert, erase, replace, and resize. And comparing and converting: the relational operators, compare, and c str, for C interfaces. Notice how much of it repeats across the library. Size, empty, clear, push back, begin and end mean the same things on a vector, deliberately so. The library is built on a small number of conventions, applied consistently, which is why the second container you learn takes far less effort than the first.

Decision Guide

When to Use std::string

So which representation, and when? For any new code holding or building text, use std::string. That's the default, with no realistic exception at this stage. The same goes for text whose length isn't known in advance, and for text that must be compared, sorted, or stored in a container. Even when calling a C library, keep the string, and hand over c str at the boundary. And when reading older code that predates it, recognize the char array, and know the terminator's role. Don't convert working code without a reason.

Quick Check

Counting Moves for 1,000 Appends

Quick check. A loop appends 1,000 characters to an empty string, one at a time. Using the growth you saw earlier, roughly how many times do the characters move? And what one call, made first, would avoid every move? Pause and think. About six. Capacity roughly doubles each time, so on this library it passes a thousand after six moves. And calling reserve(1000) first gets all the room up front, so the characters never move at all.

Key Takeaways

Four Rules to Remember

To summarize. Copies of a string are independent, and equals-equals compares the text. Reallocation moves the characters, so never hold a position across a change of length. Use square brackets in loops you've bounded yourself, and at otherwise. And declare read-only string parameters as const references.

About C++ Programming at UPI Study

C++ Programming (Computer Science 242) is a self-paced online course of 84 video lessons in 11 chapters, from your first program to decisions, loops, arrays, functions, classes, files, pointers and inheritance. It carries a NCCRS credit recommendation for 3 semester credits.

Every lesson transcript is free on pages like this one, and the videos are free with a free UPI Study account. Enrolling adds a practice quiz after each lesson, the graded work and final exam that earn the credit, lifetime access, and an official transcript on completion. UPI Study has helped over 130,000 students with college credits. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.

Why take it here

Why students take C++ Programming with UPI Study

Your first real programming languageC++ teaches how programs really work: variables, control flow, functions, memory and objects. It is the base for data structures, algorithms, systems and game programming, and for most computer-science degrees.
Credit at a fraction of the priceThe same 3 credits can cost $750 or more at a US college. Here it is one payment, self-paced, with lifetime access.
Finish your degree soonerTransfer credits reduce the courses you still owe, so you can graduate earlier or lighten a heavy semester.
Strengthen an applicationA completed college-level course on an official transcript shows admissions and scholarship committees you can do the work.
Study on your own scheduleNo start dates, no deadlines. Watch the lessons, practice, and take the final when you are ready.
130,000+students helped with college creditsACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.

Where the credit goes

Universities that work with NCCRS

C++ Programming carries a NCCRS credit recommendation. These universities work with NCCRS; some are UPI Study's signed partners. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.

Find my college → Not listed? Ask Athena in the corner of this page, or book a 15-minute call.

FAQ

Questions students ask us

About The String Class Toolkit

What is value semantics for std::string, and how does it affect copying and comparing?
Value semantics means a std::string owns its characters and behaves like an int. After string b = a; b = "Indore"; the string a still holds Bhopal, because b is an independent copy. Also, a == b compares the text. Two char pointers compared with p == q compare only addresses, so arrays that spell the same word can still test unequal.
What is the difference between size and capacity of a C++ string?
Size is how many characters a string currently holds, while capacity is how many it can hold before it must move to a bigger block. Capacity is at least the size. Appending past capacity allocates a larger block, moves every character, and frees the old one. That invalidates any pointer, reference, or iterator into the string. Calling reserve first avoids those moves.
What do begin() and end() mean when reading iterator code for a string?
begin() returns an iterator to the first character, and end() returns one to the position just past the last character. Together they form a half-open range, so end() is a stopping marker that is never dereferenced. That is why the loop is written for (auto it = s.begin(); it != s.end(); ++it), using not-equal. Vectors and other standard containers use the same convention.
How should I pass and return strings in C++ without making needless copies?
Pass a string the function only reads as a const reference, such as void report(const std::string& s), to avoid copying every character. Use a plain reference when the function must modify the caller's string, and a by-value parameter only when it needs its own copy. Return a new string by value, but do not return a reference to a local string, because it is destroyed when the function ends.

About the C++ Programming course

How many college credits is C++ Programming?
C++ Programming (Computer Science 242) carries a NCCRS credit recommendation for 3 semester credits. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.
How much does C++ Programming cost and what is included?
$250, paid once, with lifetime access: all 84 video lessons, a practice quiz after each, the graded work and final exam, and an official transcript when you finish. Students who want several courses choose UPI Study PRO instead.
Which universities accept UPI Study credits?
UPI Study has signed partner agreements with universities such as Thomas Edison State University, University of the People and Charter Oak State College, and works with universities such as Penn State, SNHU and SUNY. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities. Use "Find my college" on this page to check yours.
How long does C++ Programming take?
It is self-paced with no deadlines. The 84 lessons total about 0 hours of video; most students add reading and practice time and finish in a few weeks to a few months, on their own schedule.
How are the exams done?
Quizzes and assignments are online in the course. The final exam is taken online with proctoring; a person on the UPI Study team checks assignments, usually within two days.
How do my credits reach my college?
When the course shows 100% complete, request the official transcript from your dashboard. It is sent to the college you name, and you can send it to more than one. Check your college first with "Find my college" on this page, or ask Athena.

Ready for the full course? Earn 3 credits in C++ Programming.

84 video lessons, a quiz after each one, and the graded work that earns the credit. Recommended for credit by NCCRS.

C++ Programming
3 credits · NCCRS
Enroll →