I am writing a small program for my personal use to practice learning C++ and for its functionality, an MLA citation generator (I'm writing a large paper with tens of citations).
For lack of a better way to do it (I don't understand classes or using other .cpp files inside your main, so don't bother telling me, I'll work on that when I have more time), I am writing a function for each type of citation. I might break this down into a function for each reused code if I get more time.
My question is: how does the std::cin object work? I am currently reading in with std::cin >> for the strings I expect to be single words, and getline(std::cin, string) for the strings with spaces. I am not getting the right output, though. I just want to know how std::cin works and why I keep unexpectedly skipping over some some inputs (for instance, it skips over webPage instead of giving me a chance to input into it).
void webCit()
{
std::cout << "Leave any unknowns blank.\n";
std::cout << "Author last name: ";
std::string lastName;
std::cin >> lastName;
if (lastName.size() != 0)
{
lastName = lastName + ", ";
}
std::cout << "Author first name: ";
std::string firstName;
std::cin >> firstName;
if (firstName.size() != 0)
{
firstName = firstName + ". ";
}
std::cout << "Article title: ";
std::string articleTitle;
getline(std::cin, articleTitle);
if (articleTitle.size() != 0)
{
articleTitle = "\"" + articleTitle + ".\" ";
}
std::cout << "Title of web page: ";
std::string pageTitle;
std::cin >> pageTitle;
if(pageTitle.size() != 0)
{
pageTitle = pageTitle + ". ";
}
std::cout << "Publication date: ";
std::string publicationDate;
getline(std::cin, publicationDate);
if(publicationDate.size() != 0)
{
publicationDate = publicationDate + ". ";
}
std::cout << "Web address: ";
std::string webAddress;
getline(std::cin, webAddress);
webAddress = "<" + webAddress + ">. ";
std::cout << "Date accessed: ";
std::string dateAccessed;
getline(std::cin, dateAccessed);
if(dateAccessed.size() != 0)
{
dateAccessed = dateAccessed + ". ";
}
std::string citation =
lastName + firstName + articleTitle + pageTitle + publicationDate + webAddress + dateAccessed;
std::cout << citation; //TEST; remove after
}
EDIT: I/O
Leave any unknowns blank.
Author last name: Hooked
Author first name: Jerbear
Article title: Title of web page: title
Publication date: Web address: www.win.com
Date accessed: 4/29/09
Hooked, Jerbear. Title. <www.win.com>. 4/29/09.
As you can see, something is going wrong, because my input is getting skipped over.
-
When you use the
>>
operator,cin
reads up until the next whitespace character, but it doesn't process the whitespace. So when you havestd::cin >> str1; std::getline(std::cin, str2);
the second call will just process the newline character, and you won't have a chance to type in any input.
Instead, if you're planning to use
getline
after anoperator >>
, you can callstd::cin.ignore()
to eat the newline before you callgetline
.Edit: it works as you expected when you do
std::cin >> str1; std::cin >> str2;
since the second call will ignore all leading whitespace.
Aaron : also, note that operator>> and getline both return a boolean-compatible value that is true when it successfully read the input value, false if there was an error, end-of-file, or a formatting failure.Simon Buchan : @Aaron: to be precise, they return the istream, which is convertable to a void* which is convertable to a bool (whew!), which is the value of !is.fail(). That is why `std::cin >> lastName >> firstName;` works. -
What is happening here is that
std::cin >> firstName;
only reads up to but not including the first whitespace character, which includes the newline (or'\n'
) when you press enter, so when it gets togetline(std::cin, articleTitle);
,'\n'
is still the next character instd::cin
, andgetline()
returns immediately.// cin = "Bloggs\nJoe\nMan of Steel, Woman of Kleenex\n" std::cin >> lastName; std::cin >> firstName; // firstName = "Joe", lastName = "Bloggs", cin = "\nMan of Steel, Woman of Kleenex\n" getline(std::cin, articleTitle); // articleTitle = "", cin = "Man of Steel, Woman of Kleenex\n"
Adding '
std::cin >> std::ws
' (ws
meaningw
hites
pace) before your calls to getline() fixes the problem:std::cin >> firstName >> std::ws; getline(std::cin, articleTitle);
But it is easier to see where you missed it if you do it in the argument:
std::cin >> firstName; getline(std::cin >> std::ws, articleTitle);
sfossen : I was just about to add ws too :PJesse Beder : That's *not* what happens for multiple cin >>s!Simon Buchan : @Jesse: oh, I see what you mean about 'multiple cin >>s'. It behaves the same, I guess.Simon Buchan : Should be fixed now?
0 comments:
Post a Comment