Search

4.4b — An introduction to std::string

What is a string?

The very first C++ program you wrote probably looked something like this:

So what is “Hello, world!” exactly? “Hello, world!” is a collection of sequential characters called a string. In C++, we use strings to represent text such as names, addresses, words, and sentences. String literals (such as “Hello, world!”) are placed between double quotes to identify them as a string.

Because strings are commonly used in programs, most modern languages include a built-in string data type. C++ includes one, not as part of the core language, but as part of the standard library.

std::string

To use strings in C++, we first need to #include the <string> header to bring in the declarations for std::string. Once that is done, we can define variables of type std::string.

Just like normal variables, you can initialize or assign values to strings as you would expect:

Note that strings can hold numbers as well:

In string form, numbers are treated as text, not numbers, and thus they can not be manipulated as numbers (e.g. you can’t multiply them). C++ will not automatically convert string numbers to integer or floating point values.

String input and output

Strings can be output as expected using std::cout:

This prints:

My name is: Alex

However, using strings with std::cin may yield some surprises! Consider the following example:

Here’s the results from a sample run of this program:

Enter your full name: John Doe
Enter your age: Your name is John and your age is Doe

Hmmm, that isn’t right! What happened? It turns out that when using operator>> to extract a string from cin, operator>> only returns characters up to the first whitespace it encounters. Any other characters are left inside cin, waiting for the next extraction.

So when we used operator>> to extract a string into variable name, only “John” was extracted, leaving “Doe” inside std::cin, waiting for the next extraction. When we used operator>> again to extract a string into variable age, we got “Doe” instead of “23”. If we had done a third extraction, we would have gotten “23”.

Use std::getline() to input text

To read a full line of input into a string, you’re better off using the std::getline() function instead. std::getline() takes two parameters: the first is std::cin, and the second is your string variable.

Here’s the same program as above using std::getline():

Now our program works as expected:

Enter your full name: John Doe
Enter your age: 23
Your name is John Doe and your age is 23

Mixing std::cin and std::getline()

Reading inputs with both std::cin and std::getline may cause some unexpected behavior. Consider the following:

Perhaps surprisingly, when you run this program, it will ask you to enter your name, but then skips waiting for you to enter your name! What happened?

It turns out, when you enter a numeric value using cin, cin not only captures the numeric value, it also captures the newline. So when we enter 2, cin actually gets the string “2\n”. It then extracts the 2 to variable choice, leaving the newline stuck in the input stream. Then, when std::getline goes to read the name, it sees “\n” is already in the stream, and figures we must have entered an empty string! Definitely not what was intended.

A good rule of thumb is that after reading a numeric value with std::cin, remove the newline from the stream. This can be done using the following:

If we insert this line directly after reading variable choice, the extraneous newline will be removed from the stream, and the program will work as expected!

Rule: If reading numeric values with std::cin, it’s a good idea to remove the extraneous newline using std::cin.ignore().

Appending strings

You can use operator+ to concatenate two strings together, or operator+= to append one string to another.

Here’s an example of both, also showing what happens if you try to use operator+ to add two numeric strings together:

This prints:

4511
45 volts

Note that operator+ concatenated the strings “45” and “11” into “4511”. It did not add them as numbers.

String length

If we want to know how long a string is, we can ask the string for its length. The syntax for doing this is different than you’ve seen before, but is pretty straightforward:

This prints:

Alex has 4 characters

Note that instead of asking for the string length as length(myName), we say myName.length().

The length function isn’t a normal standalone function like we’ve used up to this point -- it’s a special type of function that belongs to std::string called a member function. We’ll cover member functions, including how to write your own, in more detail later.

Conclusion

std::string is complex, leveraging many language features that we haven’t covered yet. It also has a lot of other capabilities that we haven’t touched on here. Fortunately, you don’t need to understand these complexities to use std::string for simple tasks, like basic string input and output. We encourage you to start experimenting with strings now, and we’ll cover additional string capabilities later.

Quiz

1) Write a program that asks the user to enter their full name and their age. As output, tell the user how many years they’ve lived for each letter in their name (for simplicity, count spaces as a letter).

Sample output:

Enter your full name: John Doe
Enter your age: 46
You've lived 5.75 years for each letter in your name.

Quiz solutions

1) Show Solution

4.5 -- Enumerated types
Index
4.4a -- Explicit type conversion (casting)

185 comments to 4.4b — An introduction to std::string

  • Zero Cool

    Here is my solution for the Quiz:

    io.h

    io.cpp

    main.cpp

  • Dat coder

    Hello Alex.
    In your solution you create two variables (letters and ageperletter).Is there a reason to do that over this ?

  • gary

    hi alex, i am sorry i am little bit confuse, what does it mean:
    std::cin.ignore(32767, ‘\n’); // ignore up to 32767 characters until a \n is removed

    why does it has to be 32767 and i am still little bit confuse of ignore up to 32767 characters purpose. thanks

    • Alex

      32767 is the largest signed 16-bit integer. Any larger number could potentially overflow an int. It doesn’t HAVE to be 32767 -- we could use a smaller number, but then if for some reason you had 32767 characters before a ‘\n’ they wouldn’t all get cleared out. Unlikely, but there’s no harm in choosing 32767 over some smaller number, so we might as well.

  • The Perplexed Programmer

    Hello Alex!
    Following is a program, which is a kind of quiz. As of now, there are just 2 questions. Anyway, how do we display the score at the end? Something like "You score 1 out of 2"

  • The Perplexed Programmer

    Hello Alex!
    The following program does’nt seem to work out. Could you please help me out?

    • Alex

      What doesn’t work about it?

      • The Perplexed Programmer

        It doesnt really ask for any input after "Would you like to enter the common difference or last term?" No matter what I enter, the program ends. Please help!
        Also there was supposed to be a ‘#include <string>’ at the top. I fixed it, but the problem persists.
        Thanks!

        • Alex

          Oh. Best guess is that after extracting variable n from the input stream, the ‘\n’ is still left in the stream. So when you go to getline something, you’re extracting the ‘\n’. You can address this by calling std::cin.ignore(32767, ‘\n’); just before doing your getline call.

  • Bálint

    Hi Alex!

    I’ve done the quiz question, but when I checked the result, I noticed it is off.
    After some thinking, I realized that in my name I has UTF-8 characters, and they has length 2.
    I don’t know, probably it is compiler specific feature as well, but maybe it is worth to mention it in the tutorial, in case there are others facing the same problem..

  • Francesco

    Hi Alex,
    thanks for your tutorial.

    I’m a hobbiest Python programmer and I would like to learn C++.

    I read a lot on this site but I don’t understand how to interact with operating system.

    In Python if I want to take the list of files present in a directory and put them in a vector (array) I have to wrote a few lines of code using the standard library.

    Is there a way to do this with C++ STL? C++ is very complicated and I don’t understand how to write a function that does this.

    How about a string search in a file and put some data in an array?

    Thanks

    • Alex

      Some things that are easy in modern languages like python are surprisingly complicated in C++. Directory access is one of those things that C++ does not make easy to do in a cross-platform compatible way.

      In C++17 (slated to be released later this year), it looks like they’re adding a std::filesystem library to iterate through a directory. You could also use a third party library like Boost.

      C++ does provide the ability to open and read file data. That’s covered in chapter… 19 I think.

      • Francesco

        Thank you, so my doubt is foundated 😀

        If I understood correctly the external library that performs directory access uses C code, isn’t it correct?

        So, If I would like to write a Linux-only application the only easy-way to access to file system (without using external library) is to use C++ system() function, correct?

        Thanks a lot

        • Alex

          > If I understood correctly the external library that performs directory access uses C code, isn’t it correct?

          If you’re talking about Boost, I’m not sure what they’re using under the hood.

          If you’re writing a linux only application, the unix OS should provide functionality to directly access the file structure (e.g. via OS-specific functions opendir(), readdir(), and closedir()). See this thread on Stack Overflow for more information about how to do this.

  • Bowen

    Hello Alex,

    I’m pretty sure this will be answered in a future lesson (or maybe in this comment section if I missed it), but is there a way to not consider the space between the person’s first and last name since the number of letters in a person’s full name will always be 1 more than it actually is because of the space.

    Thanks in advance! 😀

    • Alex

      Not trivially. Probably the best thing to do would be to iterate through the string, counting how many spaces the user entered, and then subtract those out.

  • Ritesh

    hi alex
    like you said when we have to enter name after choice, it skips because 2n is entered, and n is stored in the input stream, i am getting a little confused on this simple program
    #include<iostream>
    using namespace std;
    int main()
    {
           int x;
           cin>>x;
           char c;
           cin>>c
           cout<<x<<" "<<c;
           return 0;
    }
    when i run the program it asks to enter both integer and character and then displays them as both so my question is if numericn is always entered then shouldn’t the output skip the part when it has to enter the character as n would be in the input stream same to what is happening in that choice, name program

  • Deepti

    Hi Alex,

    I am practicing some problems on strings. I wanted to know whether string class or c-style strings are widely used? Basically which one should I get familiarized with.
    Deepti

    • Alex

      You should get familiarized with both, as they are both widely used in different cases. But std::string should be favored whenever you can.

      • Deepti

        Thanks for your input.

        Alex,
        Below is program on reverse of a string using string class. In the for loop, the characters are getting printed, however, the cout statement is not displaying the whole string. Please help..

        #include<iostream>
        #include<string>
        using namespace std;

        int main()
        {
            string s;
            string rev_s;

            getline(cin,s);

            int i,j;

            j=s.length();

            for(i=0;i<s.length();++i)
            {
                rev_s[i]=s[j-1];
                cout<<rev_s[i]<<endl;
                j-;
            }

            cout<<rev_s;
            return 0;
        }

        • Alex

          This program doesn’t work because the length of rev_s is 0, and you’re using [] to try to set characters in the empty string.

          To fix this you can use the reserve function to first reserve memory for rev_s:

          Then set your characters. Don’t forget to ensure rev_s has a valid null terminator.

          • Deepti

            Thanks Alex.
            Not sure why this is not running as expected.
            #include<iostream>
            #include<string>

            using namespace std;

            int main()
            {
                string s,rev_s;
                //string rev_s;

                getline(cin,s);

                int i,j;

                j=s.length();
                rev_s.reserve(j);

                for(i=0;i<s.length();++i)
                {
                    rev_s[i]=s[j-1];
                    cout<<rev_s[i];
                    j-;
                }
                //rev_s[i]=’\0′;
                cout<<rev_s;
                return 0;
            }
            No output is shown at  cout<<rev_s statement.

            • Alex

              Because I told you the wrong thing. Sorry. You should be using the resize() function, not the reserve() function.

              • Deepti

                Thanks Alex.
                This program worked now.
                I have another question… Are there any specific sites that you are aware of for practicing C++ problems? As the OOPS concepts for me, seem quite difficult and am not able to find sites that provide problems from basic level..
                It would be great if you could help me in this direction.

  • Hi again Alex and other commenters,

    I came up with this as a solution to the quiz, but instead of using static_cast I simply made the age variable a double and moved the calculation to a function, it seems to work ok but I’m not sure if I made an error along the way, what do you think?

    • Alex

      This is fine, although it would be better to read in the user’s age as an integer.

      • Hi Alex thank you for your reply,
        I had a feeling that you might say that, for my listing that would suggest passing the age as an integer into the function and then using static_cast<double>age at line 30 in my function, is this what you mean?

          • Ok thanks, noted and applied Alex, I am sorry for all the questions but, as I am just getting started with C++ it’s nice to understand how to apply best coding practices right from the start.

            And guess what, it still works great
            Thank you again 🙂

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter