Skip to content
C++ Better Explained
Go back
C++ string vs char Array: Which Should You Use?
Edit page

C++ string vs char Array: Which Should You Use?

C++ has two ways to work with text: std::string (a modern class from the standard library) and char arrays (C-strings inherited from C). Understanding both is important — but choosing between them for new code is usually straightforward.


C-Strings: The Old Way

A C-string is a char array with a null terminator (\0) at the end:

char name[] = "Alice";
// Stored as: ['A', 'l', 'i', 'c', 'e', '\0']
// Length: 5 characters + 1 null terminator = 6 bytes

The null terminator marks where the string ends. Every C string function (strlen, strcpy, strcat) relies on it.

#include <cstring>  // C string functions

char str1[] = "Hello";
char str2[20];

strcpy(str2, str1);   // Copy str1 into str2
strcat(str2, " World");  // Append " World"
cout << strlen(str2); // 11

The problems with C-strings:


std::string: The Modern Way

std::string is a class that manages the character data for you:

#include <string>

string name = "Alice";
name += " Smith";   // Concatenation with +=
name.append("!");   // Append method
cout << name.length();   // 12 — knows its own length
cout << name;            // Alice Smith!

What std::string gives you:


Side-by-Side Comparison

Concatenation

// C-string
char result[50];
strcpy(result, "Hello");
strcat(result, ", world");   // Dangerous if result is too small

// std::string
string result = "Hello";
result += ", world";   // Safe — grows automatically

Getting Length

// C-string
char str[] = "Hello";
int len = strlen(str);   // Scans until \0 — O(n)

// std::string
string s = "Hello";
int len = s.length();    // O(1) — stored internally

Comparison

// C-string
char a[] = "apple";
char b[] = "apple";
if (strcmp(a, b) == 0) { ... }   // Must use strcmp — == compares pointers!

// std::string
string a = "apple";
string b = "apple";
if (a == b) { ... }   // == compares content naturally

Copying

// C-string
char src[] = "Hello";
char dest[10];
strcpy(dest, src);   // Undefined behavior if dest is too small

// std::string
string src = "Hello";
string dest = src;   // Safe copy — string manages its own memory

Finding a Substring

// C-string
char str[] = "Hello world";
char* found = strstr(str, "world");
if (found) cout << "Found at position: " << (found - str);

// std::string
string str = "Hello world";
size_t pos = str.find("world");
if (pos != string::npos) cout << "Found at position: " << pos;

Converting Between Them

std::stringchar array:

string s = "Hello";

const char* cstr = s.c_str();    // Pointer to null-terminated C-string
                                  // Valid as long as s is not modified

char buf[50];
strcpy(buf, s.c_str());          // Copy into a char array

char array → std::string:

char cstr[] = "Hello";
string s = cstr;                 // Direct construction
string s2(cstr, 3);             // Take first 3 chars: "Hel"

When to Use Each

Use std::string for:

Use char arrays for:

// C API requires char* — use c_str() to bridge
std::string filename = "data.txt";
FILE* f = fopen(filename.c_str(), "r");  // c_str() gives const char*
If you're looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you're a complete beginner or looking to solidify your understanding. Just $19.

Common Mistakes

Comparing C-strings with ==:

char a[] = "hello";
char b[] = "hello";
if (a == b) { ... }  // Compares pointer addresses — almost always false!
// Use: strcmp(a, b) == 0

Writing past the end of a char array:

char buf[5];
strcpy(buf, "Hello World");  // Buffer overflow — writes beyond buf!
// Use std::string instead, or check size first

Returning a pointer to a local char array:

const char* getDangerousString() {
    char local[] = "Hello";
    return local;  // Dangling pointer — local is destroyed on return
}

// With std::string, this is fine:
string getSafeString() {
    return "Hello";  // Returns a copy — safe
}

Summary

Featurechar arraystd::string
SizeFixed at compile timeDynamic, grows automatically
Length trackingManual (or strlen)Automatic (.length())
Concatenationstrcat (error-prone)+ or += (safe)
Comparisonstrcmp==, <, >
Copyingstrcpy= assignment
Buffer overflow riskYesNo
C API compatibilityNativeVia .c_str()
Ease of useLowHigh

Recommendation: Use std::string for all new C++ code. It’s safer, easier, and just as fast for most purposes.



Take Your C++ Further

If you’re looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you’re a complete beginner or looking to solidify your understanding. Just $19.

👉 Get the C++ Better Explained Ebook — $19

📋

Free Download: The 10 Mistakes Every C++ Beginner Makes

A free 1-page checklist that shows the exact traps that slow down every C++ beginner — so you can avoid them from day one.

🔒 No spam. Unsubscribe anytime.


Edit page
Share this post on:

Previous Post
C++ Struct vs Class: What's the Difference?
Next Post
C++ Ternary Operator: How to Use ? : in C++