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.


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:

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.


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.


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
4.4a -- Explicit type conversion (casting)

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

  • Finn St. John

    Can you show tell me what lesson I can learn static_cast so that it will output a float instead of an integer?

  • John

    "To use strings in C++, we first need to #include the <string> header to bring in the declarations for std::string."

    I noticed that this is not needed for GCC 6.3.0 (C++11), the code below compiles, links, and runs without including the <string> header.


    Enter your full name: Peter Griffin
    Enter your age: 42
    Your name is Peter Griffin and your age is 42

    • John

      Just a note, the code compiles & links with

      g++ -Wall -std=c++98 -pedantic-errors main.cpp

      i.e. after the C++98 standard as well…

    • Alex

      Your compiler may be including the string header for you, or iostream may be including it. Regardless, it is proper form to include it yourself, as you should always explicitly include all dependencies.

  • Mr. Doubt

    From what I tested, uninitialized strings don’t carry garbage data like other variables.
    Is this correct? If so, any simple explanation why?

    • Alex

      Generally speaking, fundamental types in C++ are not initialized by default. However, non-fundamental types generally _are_ initialized by default if you do not provide an initializer. std::string is a non-fundamental type, so it gets default initialized.

  • Kiril

    Well my code was

    But how to count the letters only, because with .lenght we get the space between the name also counted and if that happen practically our program calculates a wrong value.
    for example, my name: Jack Richards, the length of that name is 12
    but the program counts the space between Jack and Richards and get’s length 13.

    so how we get length without the spaces between?

    • Alex

      If you wanted to remove spaces, you’d need to identify how many spaces were in the string, and subtract those from the string length. This is possible to do like this:

  • OT Young

    When I made my program for the quiz I initialized the ‘age’ variable as a double, and I did not static cast when making the division happen. Is it better practice to initialize my numerical variables as int and static cast them later than to initialize variables simply how you’d use them?

    • Alex

      It’s better to use whatever data type best represents your data. If you’re storing only integer ages, then you should use an integer (and static_cast to a floating point if you need to do floating point division). If you need to store fractional ages (e.g. 40.5) then you should use a floating point number.

  • James Ray

    Hi Alex,

    "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"

    I think this should say:

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

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

    May you please explain more about how this works: “std::cin.ignore(32767, ‘n’);? What does it mean: “ignore up to 32767 characters until a n is removed”?

    • Alex

      No, the sample program is correct -- the program does not work as expected.

      std::cin will remember any characters that were input that could not be extracted to a variable, so they can be subsequently extracted. If we want to get rid of those, we can use std::cin.ignore to do so. The 32767 tells the ignore function to ignore up to 32767 characters (more than we’re likely to ever need to ignore), and the ‘\n’ tells ignore to stop ignoring characters if it reaches a ‘\n’ character. Since all user input should be ‘\n’ terminated, this essentially clears out everything.

      • James Ray

        Hi Alex,

        OK, I tested the code myself and I see it runs as you say. Confusing, but I think I understand. Ray gets stored in the next cin for age, so it skips reading the input from the user, and goes straight to printing the output.

        OK, that explanation about ignore makes sense, I guessed that was what it meant but it was good to have that clarification.

  • Nguyen Long

    Hi Alex,
    Thank you for all your helpful tutorial!
    However, I want to ask how to put and return std::string in the formula.
    And I know char can be used to store a character, but not characters. Do we have anything to hold characters?
    Thank you!

    • Alex

      > However, I want to ask how to put and return std::string in the formula.

      I’m not sure I understand what you’re asking here.

      char is used to store a character. std::string can be used to store a collection of sequential characters.

  • Avijit Pandey

    I accidently deleted my first comment
    Here is the code:

    I don’t understand what is wrong with it.
    when I compile it I get these errors

    |11|error: no matching function for call to ‘getline(std::istream&, std::string (&)())’|

    |19|error: request for member ‘length’ in ‘name’, which is of non-class type ‘std::string() {aka std::basic_string<char>()}’|

    i am using codeblocks for this.
    I tried your code in the solution and it worked perfectly but yours and mine seem pretty much the same to me
    so what is wrong with it??

    • Alex

      You’ve defined variable name incorrectly, and this is confusing this compiler. Instead of:


      • Avijit Pandey

        That did it! Thanks a lot!
        but i still don’t understand the difference between name() and name.

        • Alex

          name is just an identifier that we can give to a variable or function. name() means execute the function named name.

          So string name() doesn’t make any sense, because we’re telling the compiler “define a new string variable and give it the identifier of the function call of the function name”. What?! Similarly, std::cout << name doesn’t make sense if name is actually a function, because what does it mean to print the value of a function’s identifier, rather than the value returned by the function call?

  • Roy

    I have a question: when mixing std::cin and std::getline, you have to remove the newline from the stream after using std::cin, by making use of std::cin.ignore. But why not avoid the issue altogether and use std::getline exclusively? Would there be a disadvantage to using only std::getline instead of std::cin?

    • Alex

      You should use the right tool for the job at hand. If you want to read up to the end of a line (including whitespace), use std::getline. If you want to read up until the first whitespace, use std::cin and manually remove any ‘\n’ you don’t want via std::cin.ignore().

  • Józef

    Hi. I kind of dont get the cin.ignore() function. I have this code and when I use cin.ignore() right after entering name I have to press Enter again to evaluate to next line. Why is that?

    • Alex

      cin::ignore has two parameters: the first is the number of characters to get from the input, and the second is the special character (called a delimiter) that will cause the function to stop early.

      When you do a getline to a std::string, all of the input you type (ending with a ‘\n’) is extracted to the string. getline() also discards the ‘\n’, which is key to the next step.

      Then you do cin.ignore(999, ‘\n’). This tells the compiler, “start discarding characters from std::cin until you hit 999 character or a ‘\n’, whichever comes first”. If there were characters in std::cin waiting to be extracted, it would process through those first. But because getline() extracted everything, there’s no input waiting.

      Because there’s no input in std::cin already, std::cin will ask the user for input. It will continue to do this until the user types 999 characters, or until you hit enter.

      So, in short, cin.ignore() makes you hit ‘\n’ again because getline() discarded the ‘\n’ from the previous string.

      If it had not done so, the ‘\n’would have been left inside std::cin. Then when cin.ignore() ran, it would have extracted ‘\n’ from std::cin and discarded it. Since that matches the second parameter of ignore(), it would have stopped (not asking the user for any input).

      So, in other words, cin.ignore() is useful if you know that some particular input you want to get rid of is inside std::cin, or if you want to ensure the user has to hit enter.

  • In the following snippet it complains about converting from unsigned int to int[uniform initialisation using the length of string function ] but it works fine with direct initialisation and copy initialisation. I was wondering why this happens??

    Error    1    error C2397: conversion from ‘unsigned int’ to ‘int’ requires a narrowing conversion    

    I am using VSExpress 2013 and have used uniform initialisation before too.

    • Alex

      The length() function returns an unsigned integer, and you’re using that value to initialize a signed integer. As long as the length of your string falls within the range of a signed integer, this will be fine. But if it ever does not, your code will break (as length will end up negative).

      • Thank you for your reply. But i was wondering how a string could have negative length. Could you give an example?

        Also Thank You very much for creating/maintaining this site. It is very helpful to learn a language from home. I have recommended this site to my friends too.

        • Also why is it not a problem with direct initialisation and copy initialisation? how do they defer from uniform initialisation?

          • Alex

            It should be a problem with all three. It’s just that uniform initialization is less permissive about what kind of implicit conversions it will do (which is a good thing).

        • Alex

          A string can never have a (valid) negative length. Let’s consider a simple example where an integer is only 8 bytes. In this case, an unsigned integer would have range 0 to 255, and a signed integer from -128 to 127. If the length function returned an unsigned integer between the range 128 to 255 (which is a valid string length), then when you converted that number to a signed integer, it falls outside the range of your signed integer. Your signed integer will interpret the unsigned integer as a signed integer, and the result will be negative (due to the way unsigned and signed integers are stored in binary).

  • Mike

    Alex please help

    • Alex

      Not sure. It seems weird to me to have the same statement in the while condition and in the subsequent if statement condition. I think that will cause your program to skip characters.

  • Garry E

    Hi Alex
    Is it possible that you slipped pointers in on us quietly without warning? The answer to my question might
    then be that the long long int returned by the sizeof function refers to an array(?) of pointers and that sufficient memory for 32767 bytes would be allocated when the program was compiled triggered by the keyword
    "string". Guessing that the C++ ignore() function in this case corresponds to the C free() function.

    • Alex

      Kind of. 🙂 The address of the dynamic memory allocated by the std::string is held in a pointer. But you don’t need to worry about that at all to use a std::string. It’s just an internal detail of how std::string works.

      The ignore() function doesn’t have anything to do with strings -- it has to do with ignoring one or more characters that have been buffered for input but not extracted yet. The analog in C++ to C’s free() function is the delete keyword. We’ll also cover this in chapter 6.

  • Garry E

    Hi Alex- To get a better idea of how strings work I wrote the following program:

    #include <iostream>
    #include <string>

    int main()
        std::cout << " Enter a string of letters: ";
        std::string name;
        std:: getline(std::cin, name);
        std::cout << " Your string is: " << name <<"n";
        std::cout << " Your string has " << name.length() << " letters. " <<"n";
        std::cout << " Your string occupied " << sizeof(name) << " bytes of storage space. " <<"n";
        return 0;    

    I found that no matter how many characters (up to a thousand or so) I entered the sizeof function always returned a size of 8 bytes.I get it that the max string can be 32767 chars long.  All this is well and
    good but I am confused, because if each char occupies 1 byte does the max string occupy 32767 bytes?
    How is the string stored?

    • Alex

      It’s hard to answer this question at this point, but I’ll try. There are two ways to allocate memory -- statically (which is what we’ve been doing so far), and dynamically (which we’ll cover in chapter 6). std::string uses dynamic memory to hold the chars.

      sizeof() has a limitation in that it will only return the size of statically allocated memory. For this reason, a std::string will always return the same size no matter how much dynamic memory it’s allocated to hold the chars.

  • Mike

    Alex please help

    #include "stdafx.h"
    #include <iostream>
    #include <cctype>
    #include <fstream>
    using namespace std;
    const int siz = 2000;
    int main()
        char ch[siz];
        ifstream infile;
        cout << "Enter name of data file :\n";
        cin.getline(ch, siz);;
        if (!infile.is_open())
            cout << "progam terminating \n";
        char co[siz];
        infile.getline(co, siz);
        int count(0);
        for (int x(0); siz > x; ++x)
            if ( isalnum(co[x]))

        cout << "number of char = " << count;
    // this was supposed to count the number of chars in the text file but it cant open the text file why ??
        return 0;

    • Alex

      Not sure. It opened a file fine for me, and then began counting chars before it crashed. It’s probably looking for the text file in a different place than you think it is. Try either putting the text file in the same directory as the executable file, or typing in a full pathname to the file rather than a relative path.

  • Mike

    Alex please help.

    • Alex

      It’s crashing because you didn’t allocate an array of spr, you only allocated one.

      Instead of:

      It should be:

  • Redingard

    #include <string>
    #include <iostream>

    int main()
        std::cout << "Enter your full name.";
        std::string name;

        std::cout << "Enter your age.";
        int age;

        int letters = name.length();
        int finale = static_cast<double>(age) / letters;


        std::cout << "Your name is " << name;
        std::cout << "Your age is " << age;
        std::cout << "You’ve lived " << finale << "years per letter.";
        return 0;

    So I tried doing this quiz without looking too much at the answer, just for the format of static_cast and name.length(). Obviously, it didn’t go well. What exactly did I do wrong and how can it be improved to do what I intended?  My error list says that age is an uninitialized local variable.

    • Alex

      You’re not too far off. The main thing is you forgot to use std::cin to allow the user to input values for name and age. This means name and age have no values (which is what the compiler is complaining about).

      Another error I see is that you’re using static_cast to convert age to a double so you can do a double division, but then you’re assigning the result back to an integer variable (losing any decimal points you just worked to preserve).

  • shilpa

    #include <string>
    #include <iostream>

    int main()
        std::cout << "Pick 1 or 2: ";
        int choice;
        std::cin >> choice;

        std::cout << "Now enter your name: ";
        std::string name;
        std::getline(std::cin, name);

        std::cout << "Hello, " << name << ", you picked " << choice << ‘\n’;

        return 0;

    i did not understand why will it not ask us to enter the name during compilation!

    • Alex

      Not sure what you mean. Compilation just turns your code into something you can execute. It doesn’t actually execute anything. You have to run your program after compiling it for it to actually produce results.

  • reznov

    Note at solution code: even though std::getline() isn’t used after, to make the program expandable it’s still usually advicable to still add std::cin.ignore(xxbignumberxx, ‘\n’) at the end.

    This way when in let’s say 12 years you wanna reuse the snippet in a program that uses std::getline again later, you don’t have to deal with suprises.

    For the rest my version of it does the exact same thing so let’s move on to 4.4c 🙂

  • Lauren

    Hi Alex, I see that you said std::cin.ignore(32767, ‘n’); is meant to ignore up to 32767 characters until a n is removed. What is the significance of the number 32767? How do you know to use that number? Could you use some other number instead? Thanks.

    • Alex

      32767 is the largest 2-byte signed integer. The first parameter to std::cin.ignore() is an object of type std::streamsize, which is an implementation-defined signed integer type. Given that it’s implementation defined, we don’t know how big it is, but it’s reasonable to assume it’s at least 2 bytes.

      You could use some other number, but if you pick a number any larger you risk overflowing the integer on some machines.

      It’s actually best/technically correct to #include and use std::numeric_limits::max() instead of 32767, but that’s such an ridiculously unmemorable constant. 32767 is easier.

  • Abhishek

    Hi Alex ,

    std::cout << "Pick 1 or 2: ";
        int choice;
        std::cin >> choice;

        std::cout << "Now enter your name: ";
    std::string u;
    cin >> u;
        std::cout << "Hello, " << u << ", you picked " << choice << ‘\n’;
    output :
    Pick 1 or 2: 3
    Now enter your name: asdd
    Hello, asdd, you picked 3
    Ques: Why did "cin" not take newline character "/n" after ‘3’ ?

  • Max

    Can I simply use "cin.ignore() after cin >>;  ? I’ve used it and it seems to clear the input completely. If I am going to use cin.ignore(32767, ‘\n’), can I substitute the ‘\n’ with endl?

    • Alex

      No, you shouldn’t just use cin.ignore() with no parameters. By default it only ignores one character. You can’t substitute ‘\n’ with endl.

  • Zoickx

    “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 pick 1 or 2, but then skip asking for your name! What happened? "

    This simple inaccuracy got me stuck for a few minutes.I just couldn’t figure out why would it not Ask for name - there are no conditionals or anything like that. I even had to run it myself to make sure that’s not the case. So, I believe, what you actually meant here was "the program skips reading your name" or something like that?

    Just thought this might help improve the article.
    Otherwise, these lessons are great, thank you kindly for the good work!

  • Damien

    Hi Alex,

    Thanks again for these tutorials and your swift replies to some of my questions so far.

    My question here is in regards to the following - "std::getline() takes two parameters: the first is std::cin, and the second is your string variable".

    I would like to understand this better just for my own understanding, but at the moment am struggling. Not sure the best way to phrase this question, but could you please explain exactly what std::getline() does with the two parameters.


    • Alex

      I don’t know how std::getline() is implemented internally. But the end result is that std::cin is used to read characters from the user, which are placed in the string variable passed in as the second parameter. Unlike the extraction operator (>>), which stops extracting at any whitespace character, std::getline() only breaks on newlines, allowing you to enter text with spaces or tabs in it.

  • Kattencrack Kledge

    Little typo: "Why happened?" was supposed to be "What happened?" after the code example of "Mixing std::cin and std::getline()"

  • Vlad

    While reading 7.12, I realized that I had this question since std::array, when you said they’re slower than array[] (not std::array) because of the way they’re interpreted under the hood. So, the similar question comes: is std::string slower than C-style strings? Even if it’s the preferred way? If it is so, should it still be the preferred way only because it’s C++ native (did I get this right?) ?

  • Vlad

    Actually, that result is shown after

    straight from the console, but codeblocks shows the same result.

  • Vlad

    Hello Alex

    I tried running your program where you say std::cin yields a surprise (the result was "Your name is John and your age is Doe"), and, after I enter the two names, then enter, the program displays "Enter your age: Your name is bla and bla bla", then exits. It seems to print the asking age line, but it doesn’t wait for any input, it jumps straight to the end.

    I thought maybe it’s some typo from my part so I copy-pasted your example and I get the same results. I have codeblocks on archlinux x64. Is this some compiler problem? (it shows success, no warnings/errors).

    • Alex

      std::cin breaks on whitespace, so if you enter “John Doe”, it will only extract “John” and leave “Doe” in the input stream waiting for a future extraction. If you want to get a full line of text with spaces in it, you can use std::getline() instead.

      • Vlad

        Yes, but then how did you achieve your result? That’s what I should have gotten, too, no? Just to clarify, this is the code:

        Your result is this:

        And here’s mine (code is copy-pasted):

        I really hope it’s a quirk of codeblocks, my confidence feels threatened. 🙂

        • Alex

          No, you are quite correct. I just made a mistake in my output. Thanks for noticing and pointing it out. I’ve updated the lesson.

          Your confidence may resume. 🙂

  • Jatin

    Hey Alex, in the fourth program where you mixed std::cin and std::getline(), I was wondering why we did not worry about the newline when we used std::cin before .So I replaced the "std::getline (std::cin,name)" with "std::cin >> name" in that program. To my surprise the program ran fine except for the fact that it did not print my last name (which was after a whitespace).So, why std::cin read a newline when we used std::getline() afterwards but not when we used std::cin?

    • Alex

      std::cin skips leading whitespace, but breaks at any non-leading whitespace (space, tab, newline, etc…). So std::cin will stop reading at the space between the first and last name.
      getline gets everything up to the next ‘\n’ character.

  • Nyap

    Here’s my answer for the quiz

    seems about right

  • J3ANP3T3R

    in this example …

    std::cout <> age;

    after std::cin >> age it is no longer safe to use cin as it will ignore the next cin because it has n left in it ?

    i’m a little bit unimpressed with C++ at this point. i hope in the coming new versions they can fix the part where you have to use ignore for the hanging n on numeric inputs OR fix cin to read the whole input altogether.

    • Alex

      Yes, C++’s I/O library is frustratingly inconsistent. It’s my least favorite part of the language.

      The good news is that not many people write complicated console applications these days, and graphical applications usually have other routines for doing I/O.

  • Akhil

    Correct me if i am wrong but i think that i read somewhere that string header is a part of iostream header,so there is no need to include string when iostream header is included.

    The following code is working fine for me.

    • Alex

      You should always explicitly include all of the headers your files need. While iostream might #include string on your system/compiler, that might not be the case on another system or compiler.

  • Kingsident

    Alex, how can I use ‘and’ and  ‘or’ with strings

    • Kingsident

      take for instance when I try to do this

      #include <iostream>
      #include <string>

      using namespace std ;

      void widyConfirm( string widy)
          if (widy == "Ocktaviany" || "OCKTAVIANY" || "ocktaviany")
                  cout << "I’m going to tell you a secret…\n" ;
                  cout << "I don’t know you ba-bye\n" ;  //this line will never be executed unless I comment out the two "or’s" in the conditional statements

      int main ()
          using namespace std ;
          cout << "What is your name? " ;
          string userName ;
          cin >> userName ;
          cout << "\n" ;
          if ( userName == "Widy" || "WIDY" || "widy" )
              cout << "Is this ‘the’ Widy\n" ;
              cout << "Type in your Surname for confirmation : " ;
              string widy;
              cin >> widy;
              cout << "\n" ;
              widyConfirm(widy) ;
          else {cout << "It’s not her";} ;
         return 0 ;

      what am I not doing right?

  • Jim

    Here are some more notes.  You can also use the uniform method on strings as well as numbers. You can allocate memory using empty "" as noted in this Code::Blocks version 16.01.
    #include <string>
    #include <iostream>

    int main()
        std::string myName{""};  // allocate memory
        myName = {"Jim"};       // assign a name
        std::cout << "My name is: " << myName;

        return 0;

  • Jim

    Yes it’s strange that the Pick 1 or 2 didn’t work right  above, but with the getline for the name it worked okay.

    #include <string>
    #include <iostream>

    int main()
        std::cout << "Pick 1 or 2: ";
        int choice;
        std::cin >> choice;

        std::cout << "Hello, you picked " << choice << ‘n’;

        return 0;

  • Shane M

    Hi Alex,

             Thank you so much for posting this tutorial online, it is amazing and I appreciate your time effort to help coding noobs like me.

    My question is in the statement: [std::cin.ignore(32767, ‘n’) /code]

    what does the "32767" refer to?

    Thanks, Shane

    • Brian, Song

      Hi, Shane M

      32767 means the maximum number of characters to be discarded from ‘cin’ stream

      until the delimiter character(‘n’ in this case) would be reached

      *Note: delimiter character also will be discarded from the stream


  • sharaf

    I have a doubt, using string are you defining a variable, i think you are but in my ocurse book which i don’t like at all uses something like this

    and this gets compiled fine in code::blocks..
    so what is the difference??
    plzz tell

    • Alex

      char string[80] declares an array of 80 characters, which can be treated as a string in C and C++. I cover this case in chapter 6, when I talk about arrays and C-style strings. C-style strings used to be used a lot in the old days, but they’re dangerous, so they’re mostly avoided now.

      std::string is a class in the C++ standard library that makes working with strings easier. You should almost always use std::string.

  • sohan

    hey alex your site is helping me lot but the problem is i have to use turbo c++ compiler…. and there is some difference so plzz tell me the actual getline() command needed for turbo c++..
    hey there is visual c++ 2005 also in my school pc what compiler is that

    • Alex

      Turbo C++ is very old, no longer supported, and lacks many of C++’s newer features. I can’t answer any questions for Turbo C++ because it’s so old.

      Visual Studio 2005 is much better (though it still won’t be compliant with C++11 functionality).

  • Shiva

    Hey Alex, 3 things:

    1) ‘<iostream>’ and ‘<string>’ are missing in your reply to Mr. Ank above.
    2) Expected ‘}’ at the end of the solution-program to the quiz.
    3) As you said a header file only contains forward-declarations. The actual definitions are stored in the standard runtime library, which is included automatically by the linker during linking. My question is, is the standard runtime library too split across multiple .cpp files? So that only those files whose corresponding headers are #included in our program are linked? If the whole library is in a single file and is linked everytime, this cannot help compile faster or keep the build smaller, can it?

    • Alex

      re #3: The form the runtime library takes depends on the operating system, but it’s generally distributed as one or more static or dynamic library files that get linked into your program. On windows, these will be in .dll or .lib format. On linux, in .a or .so format.

      • Shiva

        Thanks for the info about the form in which the library is implemented, but I’m more interested to know how ‘only the things you actually need’ gets included during linking. From your explanation I infer that the standard library is a single file (or multiple files) that contains all the routines, definitions and macros for all the math, string manipulation, input/output etc. that we use in our programs. So I’m asking, when we include only iostream and no other headers that refer the standard library, does the linker knows exactly which part of the library to link? Or, since we won’t even be using all functions declared in the iostream header, is the linker smart enough to include _only_ the code of the functions that we actually used in our program? Intuitively the last seems the case, but so far you have only talked about how the standard library get included at link time, and it feels like the whole library get linked to our executables. And if this was the case it would include the code for routines that we never use in our program, which is obviously unnecessary. If I’m wrong on all accounts, can you please tell me the actual mechanism if it is not too complicated for a novice to understand? 🙂

        • Alex

          There are two ways libraries can get linked into your program: statically or dynamically. Static means the library is packaged into your executable. Dynamic means the library is kept as a separate file and loaded at runtime. Most programs load the C++ runtime dynamically, so only one copy needs to exist on the system.

          As far as I can tell, at least with Visual Studio on Windows, the C++ runtime library is a single file (msvcp100.dll).

          • Shiva

            So, put it this way - if I use a function from iostream, the #include-ed header file contains only its forward-declaration to satisfy the compiler, but the actual definition - the code that says what my function does - is linked to my executable only at the time of execution? Is this what a Dynamic Linker does? So if the library does not exist in the target system, my executable won’t run. I remember applications quit on Windows complaining about the absence of a particular Visual C++ Redistributable package. Is this the package that contains Microsoft’s implementation of the C++ runtime library on Windows?

            Sorry for asking so many questions at once..

            • Alex

              Yes, that is pretty much correct.

            • Shiva

              Yay! That’s cool. I suppose the dynamic linker is a part of the OS of the target system, just like the loader. One last question to clear everything up:

              How does the ordinary (static?) linker (which makes our executables) know a particular function is from a runtime support library, so to leave off its linking for dynamic linker? I mean, the linker always throws an error if we declare a function and not define it, but it doesn’t complain about the absence of the definitions of functions from the runtime library. Does the compiled code contain any such indications?

              • Alex

                You can configure whether you want to access the standard library statically or dynamically in your project settings. The linker will then check to ensure all the functions you call have definitions in the static or dynamic version of those libraries.

            • Shiva

              Ah! Now it is clear. This means that even if we are planning to use a dynamic library, which is to be linked at runtime, we need it installed in our systems for the static linker’s reference at build-time. So the linker does not build blindly, right? It ensures that all our functions are well defined either in our own executables or in a dynamic library they are gonna use later at runtime. And only then does it leave those dynamic references unresolved. Very clever.

              I think that’s all I needed to know. I just wanted a basic know-how, and not the nitty-gritty details of how dynamic linking is done, and you gave me just that. Reading your own modules about libraries (Appendix A.1) and some StackOverflow threads also helped a lot. It’s nice to see a lot of good folks like you helping each other out.

              Thank you so much for your time and help. Much appreciated. God Bless. 🙂

  • Ank

    If the namespace used for declaring  string is same as that for header <iostream> i.e std.Whats the need for adding another header i.e <string>?

    • Alex

      Namespaces can be split across multiple files.

      contains input and output routines (e.g. std::cin and std::cout), inside namespace std.
      contains string routines (inside namespace std).

      Having separate header files allows you to include only the things you actually need (which keeps your program smaller and compiling faster).

  • Vaibhav

    Hi Alex;
    I don’t know why but when I try to compile the very first program in this section using string it says undefined symbol string although I have included <string.h>..Please help me.. I am using turbo C++

  • AB

    I have code here, and an error I don’t know how to fix!

    • Alex

      std::string doesn’t come with a conversion to const char*, so the static_cast is failing.

      You can convert a std::string to a const char * by using the c_str() function:

  • hei_xhimi

    No matter what i try still reads numbers end outputs error after two inputs…
    Please can somebody help?!

    • Alex

      First, get rid of the cin.clear() and cin.ignore() lines, they aren’t needed.

      Second, the reason it still reads numbers is because you’re doing a getline(cin, name), which allows numeric input, and then checking to see if the string contains any numbers. If you want to disallow the user from typing numbers at all, you’re better off reading input character by character and only appending the character to the name if it’s alpha.

      Third, the reason your program crashes after entering one bad name is because changing variable name invalidates the iterator, but the iterator is still subsequently used in the for loop. Moving to character by character input is probably the best solution, but if you want to continue to do things this way, I’d write a function to check if name is all alpha or not. If not, then you can read in a new name and loop.

  • Simon

    Alex, thanks for all the tutorial. It’s really fun and easy to follow.

    I tried to put together everything learned since the beginning. And created a program that gather input from the user about his smoking habit then deliver the amount of money wasted in cigarette… (Trying to stop smoking here… and wanted to find a way to see how much i wasted in money)

    Works perfectly!

    Here is the code;

    Could you let me know if it will be a better way to actually do that, or is it ok?
    Thanks again.

    • Alex

      I think this is mostly fine for a program of this length. Stylistically, I’d make better use of whitespace to separate things (e.g. put blank lines between the code that deals with name, age, etc… to conceptually separate them a bit), and I’d put the code that does the output in a separate function. But those are minor gripes.

  • Arda

    Hey Alex. When I build this program it succeedes but when I run it, it pretty does nothing. It doesn’t write anything to the console. What’s wrong with it?

  • Probably a dumb question but how do you integrate the std::string type with calls like fopen? Do I need to do a type cast to (char *)?

  • Ethan

    When I do a basic thing in Code::Blocks such as print a string or add two numbers it builds fine but nothing shows up when it actally runs, any help on this please?

    • Alex

      A few thoughts:
      1) Are you actually running the program after compiling it?
      2) If so, is the window actually showing up and then disappearing immediately?
      3) If not, have you tried disabling your anti-virus?

  • Hridayesh

    hey alex we can also use string like this. what the purpose of using it with scope resolution operator as u did eg std::string name

    Also please tell me u used the std namespace for string type variable. how would compiler know that u are asking it for which std namespace or you are only asking it for std namespace in iostream

    • Alex

      Using the prefix std:: avoids naming conflict since there’s no ambiguity about what name is intended.

      I don’t understand your last question. Can you rephrase?

      • Hridayesh

        i mean when we #include<iostream> header and to use cout or cin objects we use std namespace either by using keyword or :: operator. here i understood that there is a namespace called std in iostream whose objects we want to use in our file. but when we #include<string> again to use its content you specified std::string i.e. your are trying to get into string header file’s std namespace aren’t you?
        my question is :  is there the same namespace in string header file also as in iostream called std?

        My another question is in my version of program i didnot use the prefix std:: for string and it works. how it worked?
        And  in your program u prefixed it with std:: , does it work like this that for string my compiler will first look up in std namespace of iostream and if it didnot find it in there it will look up in string header file and then it will compile correctly?

        • Alex

          Yes, namespaces can be split across multiple files. As you note, the iostream header has its contents inside namespace std, as does the string header. It’s the same namespace, with parts of it defined in different places.

          > My another question is in my version of program i didnot use the prefix std:: for string and it works. how it worked?

          Are you using a using statement anywhere (e.g. using namespace std;)? If so, this will cause “string” to resolve to std::string.

  • Alex

    > Isn’t it true that all assignments to a strings have to be made enclosed in parentheses and quotes like this: std::string a(“45”);or std::string myName(“Alex”);, with this one exception, myName = “John”;?

    The following are initializations (can only be used for initializing newly defined variables):

    The following is an assignment (used with string variables that are already created):

    > will myname = (“John”) work too?

    Yes. (“John”) evaluates to “John”, which can then be assigned to variable myname.

    I don’t understand your last question.

  • Jim


    Isn’t it true that all assignments to a strings have to be made enclosed in parentheses and quotes like this: std::string a("45");or std::string myName("Alex");, with this one exception, myName = "John";?  The latter seems pretty dumb, will myname = ("John") work too?

    Can the latter syntax be used instead of this:
    std::getline(std::cin, end);
    std:: cin(std::getline, end) ?

  • Nathan

    Just wanted to say thank you so much for posting such a detailed yet clear explanations. Your website rocks! 🙂

  • andy mackeroon

    Thank for the reply and suggestion Alex, I did a bit of research and I saw a few things on line that said cin and getline can cause issues when used one after the other, basically for the reason you gave, cin keeps the newline character in the buffer.

    Just tried it and it works like a charm BTW.

  • andy mackeroon

    I’m hoping I am not asking another stupid question here, but I have added a getline to the end of the name/years program (see attached code below), so I could compile it to an .exe and stop the program ending before the user has had time to read the results, but no matter what I do the second getline at the end of the code just falls through, IE it doesn’t wait for input, and I can’t for the life of me work out why. I have tried lots of different things but whatever I do it just falls thru the code. If I was to guess I would take a stab at it has something to do with characters being in the buffer still, do you need to flush the buffer somehow between uses of getline? Doesn’t sound likely, what am I doing wrong?

    • Alex

      It looks like the problem is coming from std::cin >> age. When the user enters “25\n”, the 25 is input into variable age, and the ‘\n’ is left in the input buffer.

      The call to std::getline() then eats the \n instead of waiting.

      You can fix this by adding this line between reading in the user’s age and doing the std::getline():

      • dave

        std::cin >> age;
        std::cin.ignore(32767, ‘n’);

        you didn’t actually give an example in this section or put it in the quiz solution so it left it all a bit semi-confusing. like, why is 32767 needed? will this be advanced upon later? do we only do it on the final use of cin or is it better practice to flush it every call to prevent buffer errors? does the /n from the previous getline(etc) get overwritten automatically?

        • Alex

          I updated the example to show std::cin.ignore() in use (as well as a comment as to what 32767 does). This call removes up to 32767 buffered characters until a \n is removed.

          Generally, you’ll want to use this whenever you read a numeric input from std::cin and then want to use std::getline() immediately after (to prevent std::getline() from reading in the leftover \n).

          • Alexander Kindel

            Is there anything special about the number 32767? That is, is it an arbitrary large number, where the only important thing is that it’s larger than one could reasonably expect the length of the input to be, or does it have to be exactly 32767, not, say, 32766 or 32768?

            • Alex

              I presume you’re talking about the parameter to ignore().

              32767 is the largest 16-bit signed number. 32768 could overflow, and 32766 isn’t quite as big. In most cases, a much smaller number will suffice, but there’s no harm in using a larger one so we might as well.

  • R4Z3R

    I think that just iostream library is enough.
    when I compiled the following code in Dev-C++ worked fine:

    • Alex

      If you’re using std::string, you should #include <string>.

      It’s bad form to rely on other headers including things for you, and even if it works on your system, it may not work on other compilers or systems.

  • John

    When i try to run this:

    it gives me an error that sais
    C:\Users\VeX\Desktop\Void\wofear_ex\StringEx1.cpp|18|error: invalid static_cast from type ‘std::string {aka std::basic_string<char>}’ to type ‘double’|


    • Alex

      I pasted your snippet into Visual Studio and it compiled fine. So I’m guessing you have a typo in your version of the code.

      Since the error is complaining about not being able to convert a std::string to a double, my best guess is that either:
      1) You defined age as a std::string instead of an int.
      2) You put “static_cast(name)” instead of “stat”.

    • techsavvy....aye

      I don’t know if I am only not seeing it but you haven’t put a ‘}’ at the end and afterwards it compiles just fine.

  • Todd


    "std::string is complex… They also have (It also has) a lot of other capabilities"

  • Randy

    In the quiz, why wasn’t the variable age or letters defined as a double instead of using static_cast to change it? Is there an advantage to using static_cast in this situation?

  • Devin

    This is probably not the best place to put ask this, but the

    got me thinking: Is it bad practice to put the

    in a header file? I’ll show you what I mean.



    • Alex

      In general, files should directly include the header files that they need. If myName.cpp needs string and iostream, it should include string and iostream itself.

Leave a Comment

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