2

I am learning C++ and facing an issue related to std::cout in C++. I am using vscode to program. Below is my code

    int main(){
    std::string sender_name;
    std::cout<<"Enter the sender name: ";
    std::getline(std::cin >> std::ws, sender_name);

    std::string recipient_name;
    std::cout<<"Enter the recipient name: ";
    std::getline(std::cin >> std::ws, recipient_name);

    int recipient_age=0;
    std::cout<<"Enter the recipient_age of recipient: ";
    std::cin>>recipient_age;

    std::string friend_name;
    std::cout<<"Enter your friend's name: ";
    std::getline(std::cin >> std::ws, friend_name);

    char friend_sex = 0;
    std::cout<<"Enter 'm' for friend male and 'f' for the other: ";
    std::cin>>friend_sex;

    std::cout<<"Dear " + recipient_name+"," << std::endl;
    std::cout<<std::endl;
    std::cout<<"How are you? I am fine. I miss you."<<std::endl;
    std::cout<<"Have you seen " +friend_name+" lately?"<<std::endl;

    if (friend_sex == 'm'){
        std::cout<<"if you see " + friend_name + " please ask him to call me."<<std::endl;
    }
    else if(friend_sex == 'f'){
        std::cout<<"if you see " + friend_name + " please ask her to call me."<<std::endl;
    }
    else{
        std::cout<<"if you see " + friend_name + " please ask him/her to call me."<<std::endl;
    }
    if(recipient_age <= 0 || recipient_age >= 110){
        std::cout<<"you're kidding!"<<std::endl;
    }
    else{
        std::cout<<"I heard that you just had a birthday and you are " + recipient_age;
        std::cout<<" years old." << std::endl;

        if(recipient_age < 12){
            std::cout<<"Next year you will be " + (recipient_age+1);
            std::cout<<"."<<std::endl;
        }
        if(recipient_age == 17)
            std::cout<<"Next year you will be able to vote." << std::endl;
        if(recipient_age > 70)
            std::cout<<"I hope you are enjoying retirement."<<std::endl;
    }
    std::cout<<std::endl;
    std::cout<<"Yours sincerely,"<<std::endl;
    std::cout<<std::endl;
    std::cout<<std::endl;
    std::cout<<sender_name<<std::endl;

    return 0;
}

And my output from terminal is missing some print statement

Enter the sender name: Sender
Enter the recipient name: Receiver
Enter the recipient_age of recipient: 30
Enter your friend's name: Neighbour
Enter 'm' for friend male and 'f' for the other: f
Dear Receiver,

How are you? I am fine. I miss you.
Have you seen Neighbour lately?
if you see Neighbour please ask her to call me.
rthday and you are  years old.

Yours sincerely,

rthday and you are years old. should be I heard that you just had a birthday and you are 30 years old.

I thought there is no limit for cout to print. Can anyone give me some thought about this issue ?

thp
  • 45
  • 1
  • 6
  • `std::cout<<"I heard that you just had a birthday and you are " + recipient_age;` that's actually equivalent to `std::cout<< &("I heard that you just had a birthday and you are "[recipient_age]);` - what you should do is `std::cout<<"I heard that you just had a birthday and you are " << recipient_age;`. – Ken Y-N Dec 26 '19 at 08:35

2 Answers2

3

The line

std::cout<<"I heard that you just had a birthday and you are " + recipient_age;

is wrong, because + only concatenates if it is given two std::string or an std::string on one and a string literal (or other null-terminated char*) on the other side.

It does not do what you think it does if one side is a string literal and the other side an integer, as here.

Avoid using + for concatenation. It only works with strings anyway. The correct way to output multiple objects to std::cout consecutively, formatted as strings, is with repeated <<:

std::cout << "I heard that you just had a birthday and you are " << recipient_age;

I suggest you do the same everywhere else that you used + to avoid such misunderstandings.


What + does instead when one side is a string literal and the other an integer, is that it will take the address of the string literal and add the integer to that address, returning the pointer. Consequently you are passing a pointer that starts somewhere in the middle of the string literal to std::cout <<, resulting in the behavior that you are seeing.

walnut
  • 21,629
  • 4
  • 23
  • 59
  • thank you. I followed your suggestion and it worked. May I ask why compiler can skip this issue when I used it in a wrong way ? – thp Dec 26 '19 at 08:46
  • @thp There was nothing wrong with the previous code. It just meant something else, that you were not expecting. As I explained in the last edit to my answer (and as is also explained in the other answer), `+` on a string literal and an integer basically means: "Skip that many characters of the literal"). And in general C++ is famous for not telling you when you break rules. It is your responsibility to know what you are doing. Otherwise you get [undefined behavior](https://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior) (though not here). – walnut Dec 26 '19 at 08:48
1

You cannot concatenate integers to the end of a string constant. The line

std::cout<<"I heard that you just had a birthday and you are " + recipient_age;

is saying to start printing at 30 characters past the beginning of the string when recipient_age is equal to 30.

Replace that line with

std::cout<<"I heard that you just had a birthday and you are " << recipient_age;

You will need to do this with the code that prints "next year you will be " as well.

jkb
  • 2,376
  • 1
  • 9
  • 12