Getline Repeats cout command twice, Help please!

I'm trying to make a program that's just an general assistant. It works great. Just one glitch. When i type in my login username. It repeats "write something:" twice for some reason. I've come to a conclusion that it's the getline command after the cout command that triggers it. But how can i fix that?

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <fstream>
#include <conio.h>
#include <math.h>
#include <Windows.h>

using namespace std;

string user_input;
string current_user_profile, current_user_password;
string username, password;
string newprofile;
string makenewusername, makenewpassword;
int user_birth_year;
int currentyear = 2019;
int user_age;
int current_month;
int user_birth_month;
int user_bmonth;


void TalkToAi() { //VOID TALKTOAI
while (true) {
cout << "write something: ";
getline(cin, user_input);
transform(user_input.begin(), user_input.end(), user_input.begin(), ::tolower); //TRANSLATES ALL UPPERCASE LETTERS TO LOWER CASE SO THE SYSTEM CAN UNDERSTAND!
//IF LIBRARY!!!
if (user_input == "what's my age?" || user_input == "count my age" || user_input == "whats my age?" || user_input == "how old am i?") {
cout << "when were you born?\n" << "born: ";
cin >> user_birth_year;
user_age = currentyear - user_birth_year;
cout << "what month is it? (in numbers)\n" << "month: ";
cin >> current_month;
cout << "\n" << "what month were you born? (in numbers)\n" << "month:";
cin >> user_birth_month;
if (current_month <= user_birth_month) {
user_age = user_age - 1;
}
user_bmonth = current_month - user_birth_month;
if (user_birth_month == 12) {
user_bmonth = current_month;
}
cout << "you are " << user_age << " years old and " << user_bmonth << "months old\n";
}
}
}

void StartUp() { //VOID UPONSTARTUP (WHAT TO DO, ALSO READS DIFFRENT PROFILES AND PASSWORDS FOR LOGIN)
cout << "what profile should i load?" << "\n" << "profile name: ";
cin >> current_user_profile;

fstream Myfile; //OPEN FILE TO STORE USERNAMES
Myfile.open("Usernames_and_passwords.txt", fstream::in | fstream::out | fstream::app);

if (Myfile.is_open()) {
while (getline (Myfile, username) ) { //CHECKS IF USERNAME EXISTS
if (username == current_user_profile && password == current_user_password) {
cout << "\n" << "Hello, " << username << "\n";
return;
}
}

cout << "wrong username or username unfortunately not found.\n"; //IF IT DOESN'T, CREATE NEW USERNAME
cout << "shall i create a new profile? Yes/No: ";
cin >> newprofile;
if (newprofile == "Yes" || newprofile == "yes") {
cout << "new profile username: ";
cin >> makenewusername;
Myfile.clear();
Myfile.seekg(0, ios::beg);
Myfile << makenewusername << endl;
if (newprofile == "no" || newprofile == "No") {
return;
}

}
}
}



int main() {
StartUp(); //CALLS VOID STARTUP
TalkToAi(); //CALLS VOID TALKTOAI
}
[FOR SOME REASEON THE [/CODE] THINGY CRASHED THE SERVER!]

output:
What profile should i load?
profile: Navil.
Hello, Navil
Write something: Write something:
1
2
    cout << "what profile should i load?" << "\n" << "profile name: ";
    cin >> current_user_profile;
When you enter a word and press return, this reads the word, but not the newline. The newline remains in the input buffer.

Then in TalkToAi():
1
2
3
4
5
6
7
8
9
    while (true) {
        cout << "write something: ";
        getline(cin, user_input);
        transform(user_input.begin(), user_input.end(), user_input.begin(),::tolower);
        if (user_input == "what's my age?" || user_input == "count my age"
            || user_input == "whats my age?" || user_input == "how old am i?") {
            ...
       }
}

The first time through the loop, getline() reads the newline that you entered earlier. The if() condition is false and nothing happens. The loop runs again, prints "write something" and pauses for new input.
Hello navilgameboy,


PLEASE ALWAYS USE CODE TAGS (the <> formatting button), to the right of this box, when posting code.

Along with the proper indenting it makes it easier to read your code and also easier to respond to your post.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

Hint: You can edit your post, highlight your code and press the <> formatting button.
You can use the preview button at the bottom to see how it looks.

I found the second link to be the most help.



dhayden has pointed out he problem.

When mixing formatted input std::cin >> and std::getline()it is best to clear the input buffer before the "getline".

1
2
3
cout << "what profile should i load?" << "\n" << "profile name: ";
cin >> current_user_profile;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>. 

Or you can put line 3 before the "getline"

You can also replace "std::cin" with a file stream if reading from a file.

Hope that helps,

Andy
Last edited on
Topic archived. No new replies allowed.