Something interfering with the getline function? - c++

I'm new to code and this website, so please forgive me if I'm overlooking something obvious. I've been trying to write a short little game in c++, and I need to take in user input. I want to take in more than one word so the cin>> command my book recommends is right out. The best thing I have found through research is the getline(cin,var); command. I can get this to easily work in small scale tests, but when I implement it in to my 500 line game, it never works. It will skip right over that bit of code without waiting for user imput, and set the variable to a blank space. I won't include the whole code obviously, but here is the bit in question, and my headers.
#include <cstdlib>
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
string poemend;
int heading;
int poem()
{
system("CLS");
cout<<"This poem is almost done, you just can't seem to find the perfect last word.\n";
cout<<"You can see several of your discarded endings. Most recently, 'pain'.\n\n";
cout<<"How about another go?\n>";
getline(cin,poemend);
system("CLS");
cout<<"The Prophet's old parrot spoke much of all things,\n";
cout<<"but when asked about love, squawked only ";
cout<<poemend<<" .\n\n";
Sleep(6000);
cout<<"You decide it could still use some work";
Sleep(3000);
heading = 6;
}
Again, this works perfectly if I take this in to a new blank page, so I'm really not sure what is getting in the way. I will be happy to answer any questions about the code and post more helpful bits of it if needed. Thank you so much for taking the time to read this!

Sometimes flushing the input buffer is magic. This may or may not be the case in your senario, but try this code.
cin.ignore( cin.rdbuf()->in_avail() );
cin.getline(cin,poemend);
cin.clear();
Essentially wrapping your getline with the ignore code and cin.clear.

You still have a newline which is the residue of a previous unformatted input operation. You have to discard it using std::ws. Moreover, always check if your input succeeded:
if (std::getline(std::cin >> std::ws, poemend))
// ^^^^^^^^^^^^^^^^^^^

Related

How to make this string seperate using all the punctuation instead of spaces?

As in, the spaces do not separate the lines, only the punctuation does while also including the punctuation? This is my code:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
string s = "'Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, `and what is the use of a book, ' thought Alice `without pictures or conversation?' So she was considering in her own mind(as well as she could, for the hot day made her feel very sleepyand stupid), whether the pleasure of making a daisy - chain would be worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit with pink eyes ran close by her.There was nothing so very remarkable in that; nor did Alice think it so very much out of the way to hear the Rabbit say to itself, `Oh dear!Oh dear!I shall be late!' (when she thought it over afterwards, it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural); but when the Rabbit actually took a watch out of its waistcoat-pocket, and looked at it, and then hurried on, Alice started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and burning with curiosity, she ran across the field after it, and fortunately was just in time to see it pop down a large rabbit-hole under the hedge.'";
istringstream iss(s);
do
{
string subs;
iss >> subs;
cout << "Substring: " << subs << endl;
} while (iss);
}
Since many years in C++ we have support for splitting strings in respect to any kind of pattern.
It is called std::sregex_token_iterator. You can define the separators with very powerful regexes.
For example. If you want to split a string with separators ".,;:", then you can simply define a std::regex with std::regex separator{R"([\.,;:])"}. Then you can define the iterator with std::sregex_token_iterator(text.begin(), text.end(), separator, -1)
The nice thing is that many container have so called range constructors. They take 2 iterators and then copy everything given by the iterator into itself.
For example the std::vector, has such a constructor. And if you want to split the string and have the parts in a vector, then you could write:
std::vector stringParts(std::sregex_token_iterator(text.begin(), text.end(), separator, -1), {});
The {} at the end is the default constructor that is equal to the end constructor.
Please read here for further information.
Go with Ranges!
As regards checking if a character is a punctuation mark, you can use ::ispunct.
As regards splitting when a char is a punctuation mark... you can split_when(::ispunct), which soulds just like plain English! Yeah, as simple as that: s | split_when(::ispunct) splits the string s at all the chars which are punctuation.
#include <cctype>
#include <iostream>
#include <string>
#include <range/v3/range/conversion.hpp>
#include <range/v3/view/split_when.hpp>
using namespace ranges;
using namespace ranges::views;
int main() {
std::string s = "'Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, `and what is the use of a book, ' thought Alice `without pictures or conversation?' So she was considering in her own mind(as well as she could, for the hot day made her feel very sleepyand stupid), whether the pleasure of making a daisy - chain would be worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit with pink eyes ran close by her.There was nothing so very remarkable in that; nor did Alice think it so very much out of the way to hear the Rabbit say to itself, `Oh dear!Oh dear!I shall be late!' (when she thought it over afterwards, it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural); but when the Rabbit actually took a watch out of its waistcoat-pocket, and looked at it, and then hurried on, Alice started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and burning with curiosity, she ran across the field after it, and fortunately was just in time to see it pop down a large rabbit-hole under the hedge.'";
for (auto i : s | split_when(::ispunct)) {
std::cout << "Substring: " << (i | to<std::string>) << std::endl;
}
}
to<std::string> is to convert each view obtained from split_when into an actual std::string. (You can try removing | to<std::string> and you'll see what that means.)

Trying to close c++ program at certain time returns value's (that i don't want)

Running the code returns no errors, the problem is when I try to exit the program.
Simply, when i use the exit, return or abort functions, i get this (picture below)
see code below
//First 2 libs handle info exchange
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string>
using namespace std;
main(){
string username;
cout << "Please enter a general use handel (\"username\")\n";
cin >> username;
fstream blockUsername;
blockUsername.open("Player_Data/username.txt", ios::out); //out is for writing, in is for reading
blockUsername << username;
blockUsername.close();
return 0;
}
I'm aware that similar questions have been asked, but I have not succeeded in fixing my code with those.
What I want is for the program to close with no exit values, even though I know that they are useful.
PS: It very well could be something to do with my code editor (Dev C++), or my compiler which i broke and had to fix recently.
Also side note how would i go about removing that address at the top of the terminal (and potentially replacing it with something else)?
These are printed by your IDE....if u execute the .exe output of this code...the console would just disappear after program exits and it would not be shown
Peace
try using return 0; wherever you want to exit, it's okay to have more than one return 0; in your code or to simply put it after an if statement.

C++: Flawed console output on using a conditional statement

I'm a newbie to C++ (and to programming in general). I wrote a program that reads and writes staff contact details. This code works well:
// appropriate headers...
int main()
{
char trigger{};
int options = 0;
bool testing{};
fileIps Inptbox; // for entering new data
char ext_title[20]; char ext_intercomNum[4]; char ext_dept[20];
printf("%s", "Enter Officer's Title:\n");
gets_s(ext_title, 20);
printf("%s", "Enter Officer's Intercom Number:\n");
gets_s(ext_intercomNum, 4);
printf("%s", "Enter Officer's Department:\n");
gets_s(ext_dept, 20);
Inptbox.rcv_values(ext_title, ext_intercomNum, ext_dept);
Inptbox.create_string();
testing = Inptbox.validate();
if (testing == true)
return -1;
else if (testing == false)
Inptbox.write_string();
// more code below...
My question is regarding the console output. I had tried to introduce conditional statements to enable selecting a read or write mode. The above code is for writing to file. There are more lines of code below for reading from file and they, too, worked okay.
My challenge is that once I introduce a conditional statement for the above code...
printf("%s", "Enter 1 to WRITE DATA or 2 to READ DATA\n");
cin >> options;
if (options == 1)
{
fileIps Inptbox; // for entering new data
//... rest of code...
}
// more code below...
...the output on the console is flawed, as the prompt for the first entry is displayed but is totally skipped, forcing the user to enter 'Officer's Intercom Number' first. The third prompt worked well.
To elaborate further, when I used cin to assign the value 1 to options (i.e. applying the condition), the console would immediately print...
Enter Officer's Title:
Enter Officer's Intercom Number:
...making it impossible for me to fill in the first entry (i.e. 'Title').
I struggled with this and tried several things to fix it. I used fgets() and even tried it with gets(). I revisited my classes, yet nothing worked. I read widely on things like buffering, studied questions on this site and looked through various resources on cstdio as well as ios_base and its derived classes (which was good because I learned a bunch of other things). However, unless I removed that 'if' statement from my code, nothing I else I tried worked.
So, my question is: "How can this kind of behaviour be explained and how best could I implement my code to enable me toggle between read and write mode?"
I am working with MS Visual Studio 2015.
Using the formatted extraction operator '>>' has its problems. In this case, it reads all values that can convert to an integer. However, you must give an enter to signal that you're ready. The >> operator does not process that newline. When the next time input is read, it sees the previously given newline character. Hence the 'Enter Officer's title' input is immediately set to a newline and continues. Try using something like:
std::string line;
getline(cin, line);
And test the string or convert it.

Getline() Not keeping Application Open?

I'm a first semester C++ student and in class we are building a BMI calculator (Win32 Console Application). I've gotten everything to work just fine, except for one of the instructions, which is wait for user to press enter to close application.
I had success using the system("PAUSE"); statement but in the past I would declare a string variable, like for example, initialize string genVar; and then use getline(cin, genVar); and when the user pressed Enter, the application would close, but it didnt work this time. The application would simply close. It worked just fine with pause, but not with getline().
Is using getline() for this purpose bad practice? Anyone have any clue why it didn't work?
Thank you in advance!
I know this is an old post, but look at the solution which I posted in this question:
C++ Multiple Program Issues (rand, conversion, crashing)
It explains (as chris mentioned in a comment) that getline tends to leave in a new line character in the buffer, which needs to be cleared and reset. Answer above explains it.
std::cin and std::getline do not mix well in general, you usually want to stick to one or the other in a program to avoid input errors and bugs. Your getline probably is grabbing a left over input from as earlier std::cin. I would recommend using this:
std::cout << "Press ENTER to continue...";
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
return 0;
}
you'll need to include <limits> for this to work correctly.
you can also use the getch() function in the place of std::getline() IMHO

C++: Infinite loop with a simple menu selection

The script I am working on is over a page long, so I am going to link it (one simple file):
http://pastebin.com/7BVHmQGp
I apologize for that. My problem is I get into an infinite loop in my code, for example after I select 1 or 2 for encrypting/unencrypting it lets me enter the word, and when I next enter the "shift" for the cipher it runs an infinite loop of the menu.
I had tried for so many hours to debug this, I thought it was a problem with cin, for example when you enter an invalid choice it just throws an infinite loop/
What seems to cause the infininte loops?
I think you should be ignoring the newline character instead of a space
I tried with the following and it works on VS2010
cin.ignore(1, '\n');
getline(cin, input);
Try cin.clear, I believe you are constantly reading your initial input character.
cin >> selection;
cin.clear();
This page should explain all you need to know.