Stop taking input when a blank line encounters [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am trying to stop the loop when user gives a blank line, otherwise push name and score to a vector pair. But this code is not working.
Input format:
<name><score>
e.g.:
Akash 45
My code is below:
int m;
cin>>m;
vector<pair<string,int>>player;
string name;
int score;
while(1)
{
cin>>name;
if(name.empty())
break;
cin>>score;
player.push_back(make_pair(name,score));
}
Also , I have tried the following:
if(name.length()==0)
while(getline(cin,name))
if (name=="")
None of them worked.
Can anyone help me?

`std::cin >>`
does not return with empty input. When the user wrote just the "Enter" key, the std::cin still wait.
I made the test, this is working :
std::getline(std::cin, name);
if(name.empty())
break;
Edit :
#include <iostream>
#include <vector>
#include <string>
int main()
{
std::vector<std::pair<std::string, int>>player;
std::string name;
int score;
while (1)
{
std::getline(std::cin, name);
if (name.empty())
break;
std::cin >> score;
player.push_back(make_pair(name, score));
// clear the std::cin buffer else the next std::getline won't wait next input
std::cin.seekg(0, std::ios::end);
std::cin.clear();
}
return 0;
}
the
std::cin.seekg(0, std::ios::end);
std::cin.clear();
fix the problem of the second std:getLine

operator>> ignores whitespace, and line breaks are treated as whitespace, so cin>>name will never return a blank string (baring an input failure).
To accomplish what you are attempting, you need to use get::getline() instead to read an entire line at a time. You can then test for blank lines, and can use std::istringstream to parse values from each non-blank line, eg:
vector<pair<string,int>> player;
string line, name;
int score;
while (getline(cin, line) && !line.empty())
{
istringstream iss(line);
if (iss >> name >> score)
player.push_back(make_pair(name, score));
}

There's a small program to demonstrate you how to achieve so:
#include <iostream>
#include <vector>
int main(void) {
std::string name;
std::vector<std::string> nameList;
std::getline(std::cin, name); // statement X
nameList.push_back(name);
for (; ;)
if (name.empty())
break;
else {
std::getline(std::cin, name); // recalling statement X again
nameList.push_back(name);
}
for (int i = 0; i < nameList.size(); i++)
std::cout << nameList[i] << std::endl;
return 0;
}
First of all, let the user input something before going inside the loop directly. As soon as the user hits Enter, the loop will be broken when name.empty() conditions becomes true and returns true and break statement is executed.
In the other hand, as long as the user will hit the Enter key and keep writing something line-by-line, the loop will be executed.
Notice that I've used a For loop in this case, you could do the same trick with a While loop as shown:
while (true)
if (name.empty())
break;
else {
std::getline(std::cin, name); // recalling statement X again
nameList.push_back(name);
}

Related

How do I remove the extra space on the output from this method [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 months ago.
Improve this question
I'm trying to solve this question below:
Write code to read a list of song durations and song names from input. For each line of input, set the duration and name of newSong. Then add newSong to playlist. Input first receives a song duration, then the name of that song (which you can assume is only one word long).
Input example:
424 Time
383 Money
-1
This is the code that I used:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Song {
public:
void SetDurationAndName(int songDuration, string songName) {
duration = songDuration;
name = songName;
}
void PrintSong() const {
cout << duration << " - " << name << endl;
}
int GetDuration() const { return duration; }
string GetName() const { return name; }
private:
int duration;
string name;
};
int main() {
vector<Song> playlist;
Song newSong;
int songDuration;
string songName;
unsigned int i;
cin >> songDuration;
while (songDuration >= 0) {
/* Solution is below */
getline(cin, songName);
newSong.SetDurationAndName(songDuration, songName);
playlist.push_back(newSong);
/* Solution is above */
cin >> songDuration;
}
for (i = 0; i < playlist.size(); ++i) {
newSong = playlist.at(i);
newSong.PrintSong();
}
return 0;
}
This is the message I get when I try to run my code:
Can someone please help me remove the extra space from the method? I don't know how to remove this space, I tried everything I know.
On this statement:
cin >> songDuration;
Reading stops when a non-digit character is encountered, such as the whitespace following the number. The whitespace is left in the input buffer for subsequent reading.
Then this statement:
getline(cin, songName);
Reads from the input buffer until a line break is encountered. As such, the whitespace that is present between the number and the name ends up in the front of the songName variable. That is the whitespace you are seeing in your output.
The solution is to ignore the whitespace before reading the songName.
You can use the std::ws I/O manipulator for that purpose, eg:
#include <iomanip>
...
getline(cin >> ws, songName);
However, the instructions clearly state the following about the song name:
the name of that song (which you can assume is only one word long)
So, you can alternatively use operator>> to read in the songName. It will ignore the leading whitespace for you:
cin >> songName;

How do I limit user to input a single character only in C++

I am a beginner and I'm trying to limit the user to input a single character only, I do aware of using cin.get(char) and it will only read one character from the input, but I don't want the other characters be left in buffer. Here is a sample of my code using EOF, but it doesn't seem to work.
#include <iostream>
#include <sstream>
using namespace std;
string line;
char category;
int main()
{
while (getline (cin, line))
{
if (line.size() == 1)
{
stringstream str(line);
if (str >> category)
{
if (str.eof())
break;
}
}
cout << "Please enter single character only\n";
}
}
I have used this for digit inputs and the eof works fine.
But for the char category the str.eof() seems to be false.
Can someone explain? Thanks in advance.
The eof flag is only set if you read try to read past the end of the stream. If str >> category read past the end of the stream, if (str >> category) would have evaluated false and not entered the loop to test (str.eof()). If there was one character on the line you would have to attempt to read two characters to trigger eof. Reading two characters is far more effort than testing the length of line to see how long it is.
while (getline (cin, line)) got the whole line from the console. If you don't consume it in the stringstream it doesn't matter, that stuff is gone is gone from cin when you loop back around in the while.
In fact, the stringstream isn't doing you any favours. Once you've confirmed the length of the line that was read, you can just use line[0].
#include <iostream>
using namespace std;
int main()
{
string line; // no point to these being global.
char category;
while (getline(cin, line))
{
if (line.size() == 1)
{
//do stuff with line[0];
}
else // need to put the fail case in an else or it runs every time.
// Not very helpful, an error message that prints when the error
// didn't happen.
{
cout << "Please enter single character only\n";
}
}
}

Space delimited dynamic input by user of unknown length

How can I get and then store a space delimited input in C++ from a user into an array?
Most important part is that length is unknown and input should be by user during runtime
#include<iostream>
using namespace std;
int main() {
int n=0;
string names[3];
int i = 0;
while ( getline( cin, names[i]))
{
cout<<"i = "<<i<<"\n";
cout<<names[i]<<"\n";
i++;
cout<<"i = "<<i<<"\n";
}
for(i=0;i<3;i++)
{
cout<<names[i];
}
return 0;
}
The first problem I can spot in your code is, that you provide a fixed sized array of string names[3]; to store an unknown number of inputs from the user. That certainly won't work.
To fix this use a container that can use an "arbitrary" number of std::strings;
std::vector<std::string> names;
Having this you can just use something like
std::vector<std::string> names;
std::string name;
while(cin >> name) {
names.push_back(name);
}
The problem still left is how you could end this loop.
There are several options:
Let the user use one of CTRL-D or CTRL-Z (<- subtle link)
Ask them to enter a special value like quit, exit, -1 to end inputting
Track it down to a second level to process ENTER. Use std::getline() parse all the words using a std::istringstream or break, when getline() reads an empty result.
Let's analyze these:
Is a bad choice, because it's operating system dependent and asks the user to do relatively complicated actions.
Restricts the possible inputs, and there's a method needed to escape inputs of quit, exit or alike.
Empty input like retrieved from a simple additional hit of the ENTER key is probably the most intuitive you can offer to the user.
As a solution following my proposal in 3.:
std::string line;
std::vector<std::string> names;
while ( getline( cin, line)) {
if(line.empty()) {
// end input condition
break;
}
std::istringstream iss(line);
std::string name;
while(iss >> name) {
names.push_back(name);
}
}

How to read data from stdin, for a given number of test cases in C++

This might sound silly, but it's my first time solving programming contests on line. The problem is usually described as:
Input:
First line indicates the number of test cases t.For the next 't' lines the data is entered.
I've written the following program (with the correct headers included):
vector<string> read_strings(int t_cases) {
vector<string> ip_vec;
string line, str;
int cnt = 0;
while (cnt != t_cases-1) {
std::getline(std::cin, line);
++cnt;
}
std::istringstream iss(line);
while (iss >> str) {
ip_vec.push_back(str);
}
return ip_vec;
}
But this program always gets stuck in an input loop. I've also tried to parse the line as soon as it's entered by putting iss in the first while loop. If anyone could provide me a pointer on how to solve this problem, I will be able to finally test the rest of the program.
Thanks.
You need to add the lines to the vector as they are read. The first while loop is reading through all the test cases, but is not saving them somewhere. Then next while loop tries to reads line, which is the last test case read. Try the following:
vector<string> ip_vec;
string line, str;
for (int cnt = 0; cnt < t_cases; cnt++) {
std::getline(std::cin, line);
ip_vec.push_back(line);
}
Since you're starting to learn how programming contests work, I wouldn't recommend you to store all the input given. In general, you can store the number of inputs t and for each test case, the program outputs the answer for that test before reading the next test case. For example:
for (int i = 1; i <= t; i++) {
cin >> input;
// Some computations specific to the problem
cout << output << endl; // Pay attention on how the problem wants the output to be printed.
}
If the problem doesn't give you the number of test cases, you can simply change the loop to:
while (cin >> input) {
// Computations...
cout << output << endl;
}
It's usually how I solve problems from programming contests.
EDIT: As noted by #AnkitKulshrestha, if there's more than one input that you have to read for each test case, you can simply read them like this (with three inputs, for example):
while (cin >> a >> b >> c) {
// Computations...
cout << output << endl;
}

If conditioning and String [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am very new at C++ and deeply appreciate your help!
I am trying to make a 'If' condition for a string, that is, for example:
#include <iostream>
using namespace std;
int main()
{
string message = "HELP";
int password;
cout<<"Please enter password";
cin<<password;
if (password = message);
}
else {
cout<<"Please try again...";
}
cin.ignor()
}
However Int is not for strings I believe and of course on Code::Blocks it posts the error that it doesn't function in such case. So basicaly just when someone on C++ saves a variable for int X; X = 3; for example, how can we do that with letters so that I can pop if condition message boxes!
Again thanks for helping! =D
= is assignment. == is comparision. Also, don't put semicolon after the if statement.
#include <iostream>
using namespace std;
int main()
{
string message = "HELP";
string password;
cout << "Please enter password";
cin >> password;
if (password != message)
{
cout << "Please try again...";
}
return 0;
}
Should work a little better.
This is the first problem:
int password;
The data type of password should be std::string as well, because message is std::string (which contains the valid password).
So the first fix is this:
std::string password;
Second problem is that you're using '=' in if. Use '==' (equality operator), not '=' (assignment operator).
First off, if you want the password to be anything, not just a number, use std::string.
To compare two values, use == NOT =.
#include <string>
#include <iostream>
int main()
{
std::string s1("First string");
std::string s2("Second string");
if(s1 != s2) {
std::cout << "Strings don't match!" << std::endl;
}
}
In your code, you also didn't properly close all blocks and misspelled cin.ignore().
What you probably want to do is:
#include <iostream>
// using namespace std; don't do this (its just lazy)
// Also its a bad habit to get into.
int main()
{
std::string message = "HELP";
// int password; I assume you want a password to be a string
std::string password;
std::cout << "Please enter password"\n; // Added \n to make it print nicely.
// cin<<password; The << is wrong should be >>
//
// Bu this reads a single word (separated by spaces).
// If you want the password to hold multiple words then you need
// to read the line.
std::getline(std::cin, password);
// if (password = message); This is assignment. You assign message to password.
// Also the ';' here means that nothing happens
// if it was true
//
// You are then trying to test the result of the
// assignment which luckily does not work.
// Use the '==' to test for equality.
if (password == message)
{
}
else
{
cout << "Please try again...";
}
// cin.ignor() This does nothing.
// What you are trying to do is get the program to wait
// for user input. You should do something like this:
std::cin.ignore(std::numeric_limits<std::streamsize>::max()); // Flush the buffer
std::cout << "Hit enter to continue\n";
std::cin.get();
}
You used the wrong operator on the if condition. You used = which is the assignment operator. You need to use == which is comparison. You also have a semi-colon after the if which doesn't belong and your braces for the statements aren't right,