Start Learning

As a programmer, you’re likely familiar with the concept of a string, but did you know there are three ways to build a string in C++? Do you understand their behavior in particular? In this article, we’ll go over what a C++ string is, how it differs from strings in C, and show some examples of how to use strings in everyday programming. We’ll also touch briefly on methods that can be invoked when working with C++ strings.

What is a string in C++?

Let’s jump right into the definition: in C++, a string is a way to represent a sequence of characters and to offer methods for operating on that sequence, for example, to print it, reverse it, or pass it as input to a function. Strings are most commonly used to do anything and everything in your code that’s related to text.
For those of you familiar with C, you probably know that any C code you write is also technically valid C++ code. However, you may not want to use C-style strings; C++ offers more convenient syntax. In C, the concept of a string per se does not exist. Instead, it must be represented as an array of characters. The \0 character is used to mark the end of a string. In code, this is how it looks:

char greeting_es[5] = {'H', 'o', 'l', 'a', '\0'};

C++, however, is smarter when it comes to strings. It can interpret entire strings and automatically attaches the stop character at the end. This means you don’t need to build an array of characters manually and can instead just assign strings to arrays of characters:

char greeting_fr[8] = "bonjour";

But this isn’t the only way to use built-in strings. In C++, the preferred method is to use the built-in string  type; this removes the complexity of char arrays, and the compiler automatically determines the size of the string based on the input.

string greeting_de = "hallo";

So which method should you use? 
As you might imagine, you should always use the C++ string. That way you don’t have to worry about string termination and sizes of character arrays. The C++ approach to strings is easier and simpler and has the same functionality, whereas using char for text processing can become very tedious.

Examples using C++ strings 

Now that we have a clear understanding of C++ strings and how they compare to strings in C, let’s dive into some examples of using C++ strings in our code. We can do this by exploring some methods associated with the string object, such as the very simple at() method, which allows us to extract characters in a given string.

#include <iostream>   // std::cout
using namespace std;

int main() {
  string greeting( "What's up?");
  cout << greeting.at(5) << '\n';
  return 0;
}

// output: 's'

Now let’s try a more complex method. Want to print an integer in C++? It’s not as simple as you think! Converting integers into strings can be done in various ways, the most straightforward being to use  string to_string (int val); . For example:

#include <iostream>   // std::cout
using namespace std;

int main ()
{
  string perfect = "There are " + to_string(1+2+4+5) + " months in a year.";
  cout << perfect << '\n';
  return 0;
}

// output: There are 12 months in a year.

Let’s say we want to compare two strings to each other to see if they’re the same. What’s the best approach? Just as there are two standard ways to instantiate a string, likewise there are two techniques we can use in C++ to check if strings are equal: compare() and the == operator. In code, comparison using the relational operation looks like this:

   #include <iostream>   // std::cout
    using namespace std; 
      
    void relationalOperation(string s1, string s2) 
    { 
        if (s1 != s2) 
            cout << s1 << " is not equal to " << s2 << endl;
        else
            cout << s2 << " is equal to " << s1 << endl; 
    } 
      
    // Main function 
    int main() 
    { 
        string s1("Hello World"); 
        string s2("Bonjour World"); 
        relationalOperation(s1, s2); 
        return 0; 
    } 
    
    // output: Hello World is not equal to Bonjour World

The built-in compare function that works the same would look like this:

#include <iostream>   // std::cout
    using namespace std; 
    
    void compareFunction(string s1, string s2) 
    { 
        // use compare()
        int x = s1.compare(s2); 
      
        if (x != 0) 
            cout << s1 << " is not equal to " << s2 << endl;
        else
            cout << s2 << " is equal to " << s1 << endl; 
    } 

// Main function 
    int main() 
    { 
        string s1("Hello World"); 
        string s2("Hola World"); 
        compareFunction(s1, s2); 
        return 0; 
    } 
    
    // output: Hello World is not equal to Hola World

You can try changing the two strings to be equivalent to each other, and see what your output is then.
A few more insights into these two approaches: the compare method is equivalent to strcmp(), which compares strings lexicographically, character by character, until a conclusion is reached. The == operator performs simple equality checking. compare() therefore returns an integer (0 if equal, or a nonzero number that expresses the difference between the length of the two strings), whereas == returns a boolean.

The most vexing parse

You might be unaware of this fact: there is ambiguity in C++ declaration syntax that leads to counterintuitive behavior. This issue is so important that Scott Meyers coined the phrase “the most vexing parse” to describe it. Let’s briefly touch on how it applies to strings:

// Is this:
// 1) A variable of type std::string initialized to a std::string()?
// 2) The declaration of a function that returns a std::string and has one argument,
//    which is a pointer to a function with no arguments that returns a std::string?
std::string foo(std::string());

The second interpretation actually aligns with the C++ standard, even though the first interpretation is the intuitive one. Programmers can disambiguate by enclosing the initial value of the variable in parentheses:

// Parentheses resolve the ambiguity — this is a variable
// initialized to std::string
std::string foo((std::string()));

Wrapping Up

For further insight into this topic, W3Schools has a great C++ overview, and the C++ website provides a list of member functions (known as methods in other languages) present in the standard C++ library. If you’re a visual learner, look at this excellent tutorial for understanding the memory presentation of C and C++ strings that we touched upon, while also diving into common C++ operations. Finally, GeeksForGeeks has a high-level explanation along with plenty of example code for those who learn by practicing applications.
In this article, we touched on what a C++ string is, what it looks like, and how we can use it in everyday code. We also specified the differences between C and C++ strings, showing that although C strings are valid in C++, native strings in C++ offers more convenience. Lastly, we walked through several examples of operation that include strings, such as the at, to_string, and compare methods.
Looking to learn more about C++? Sign up for the C++ Nanodegree program.

Start Learning

Stephen Welch
Stephen Welch
Stephen is a Content Developer at Udacity and has built the C++ and Self-Driving Car Engineer Nanodegree programs. He started teaching and coding while completing a Ph.D. in mathematics, and has been passionate about engineering education ever since.