Having issues reading in a string.

What am I missing?

When I try to read in my string with a getline there's an error. If I just try "cin >> question;", it skips the rest of my program and doesn't loop.
//
// main.cpp
// Fortune Teller #12
//
// Created by Raven Jamison on 12/11/19.
// Copyright © 2019 Raven Jamison. All rights reserved.
//

#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
struct Zoltar
{
int luckynum;
string prediction;
}fortuneteller[12];
void fill()
{
string fortune[12]={"As I See It Yes", "Ask Again Later", "Better Not Tell You Now", "Cannot Predict Now", "Concentrate and Ask Again","Don't Count On It", "It Is Certain", "It Is Decidely So", "Most Likely", "My Reply Is No", "My Sources Say No", "Outlook Good"};
for(int i = 0; i < 12; i++)
{
fortuneteller[i].luckynum = i;
fortuneteller[i].prediction = fortune[i];

}
}
int randomnum()
{
int num = rand() % 12 + 1;
return num;
}
string randomfortune(int random)
{
return fortuneteller[random].prediction;
}
void output(string fortune, int luckynum)
{
cout<<fortune<<endl;
cout<<"Lucky number: "<<luckynum<<endl;
}

int main()
{
int response;
string question[50];
int decision = 1;
fill();
while (decision == 1)
{
int random = randomnum();
string fortune = randomfortune(random);
cout<<"Would you like to type your question (type 1) or mentally ask (type 2)?"<<endl;
cin >> response;
cout <<"You may now type out your question or mentally ask (once done type 'done')."<<endl;
getline(cin, question);
output(fortune, random + 1);
cout <<"Would you like another prediction? (type 1 for yes and 2 for no)"<<endl;
cin >> decision;
}
}
If you are getting line skips when using getline, put a cin.ignore() after each cin.
Mixing >> and getline often leads to problems. I usually recommend one of two solutions.

1. The easy solution
Always use std::ws, to ignore any leading whitespace, before using getline.

1
2
3
std:.string line;
std::getline(std::cin, line);
std::getline(std::cin >> std::ws, line);

This works great if you don't want to be able to read empty lines or care about the space at the beginning of a line.

2. The "correct" solution
The real "problem" is that >> doesn't remove anything after reading the value. This means that if there is a newline character after the value it will still be in the input buffer so if you use getline afterwards it will find a newline character right away and return an empty string. The solution is to always remove the whole line (including the newline character) after you are finished reading a line of input with >>.

1
2
3
int value;
std::cin >> value;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

You could also have used simply std::cin.ignore(); but then it would not ignore additional input (whitespace or not) that the user might have inputted at the end of the line.

Instead of std::numeric_limits<std::streamsize>::max() you could use any large value. The important thing is that it's longer than the line that the user enters.
Last edited on
Topic archived. No new replies allowed.