I want to get a line of strings and write every word into it's own variable, so that I can use them for example in if clauses.
I tried:
cin >> var1;
cin >> var2;
cin >> var3;
cin >> var4;
But this only works if 4 words are entered. I need a way to count the words because I don't know if it's 1,2,3,4 or more words the user enters.
Maybe there is a way with getting the whole string:
getline(cin, string1);
And cut it into words after that.
Sorry, I searched a lot but I can't find a way.
I also tried to write the cinbuffer into a variable, but the only way I can do this is with
cin >> varx;
Which is only usefull if there is something in the cinbuffer. If not, the user gets asked for input again.
EDIT: Just found this, works for me. Thanks Anyway!
C++ cin whitespace question
You’re on the right track. You can read a line with getline() then use an istringstream to treat that line as a stream of its own. Change this for whatever type T you happen to be using.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>
int main(int argc, char** argv) {
using namespace std;
vector<T> values;
{
string line;
getline(cin, line);
istringstream stream(line);
// Read values into vector.
copy(istream_iterator<T>(stream), istream_iterator<T>(),
back_inserter(values));
}
cout << "Received " << values.size() << " values:\n";
// Copy values to output.
copy(values.begin(), values.end(),
ostream_iterator<T>(cout, "\n"));
return 0;
}
Writing things to different variables like this is usually the wrong answer. It seems like you want something like an array.
sounds like you use getline
http://www.cplusplus.com/reference/string/getline/
then use something like boost split to dump each item into an array
http://www.cplusplus.com/faq/sequences/strings/split/
Related
I am trying to create an vector <int> whose size is not pre-defined. It should take in numbers as long as there are numbers in the input terminal and should stop reading when I hit Enter. I tried many solutions including the ones given here and here. In the second case, I can enter a non-integer to terminate the input to the vector. If I use the first solution (code added below), it listens to the input indefinitely.
Code:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>
using std::cout;
using std::cin;
using std::vector;
using std::string;
using std::istringstream;
int main()
{
//cout << "Enter the elements of the array: \n";
//vector <int> arr ( std::istream_iterator<int>( std::cin ), std::istream_iterator<int>() );
vector <int> arr;
string buf;
cout << "Enter the elements of the array: \n";
while(getline(cin, buf))
{
istringstream ssin(buf);
int input;
while(ssin >> input)
{
arr.push_back(input);
}
}
cout << "The array: \n";
for(size_t i = 0; i < arr.size(); i++)
{
cout << arr[i] << " ";
}
return 0;
}
1) I don't feel that typing in a character or a very large number to end listening to input is very elegant. However, the solution with istringstream seems to be the way to go. I am not sure why it doesn't work.
2) Is there any way to detect the Enter from keyboard to terminate listening to input? I tried using cin.get(), but it changed the numbers in the vector.
3) Any other methods or suggestions?
Let's take things one step at a time.
We want to read up until enter is pressed. That means you probably want to use std:getline to read a line.
Then you want to parse it, so you want to put the line into an istringstream.
Then you want to read numbers. While you're reading them, you apparently want to ignore anything other than digits, and you want to keep reading even if you get to a group of digits that can't be converted to a number.
That leaves a few things that aren't entirely clear, such as what to do with that input that's too large to convert? Do you want to just skip to the next? Do you want to read some digits as a number, then read remaining digits as another number?
Likewise, what do you want to do if you get something like "123a456"? Should it be skipped completely, read as "123" (and the "a456" ignored)? Should it be read as "123" and "456", and just the "a" ignored?
For the moment let's assume that we're going to read space-separated groups of characters, and convert all those to numbers that we can. If something is too big to convert to a number, we'll ignore it (in its entirety). If we have a group like "123a456", we'll read the "123" as a number, and ignore the "a456".
To achieve this, we can do something like this:
std::string line;
std::getline(infile, line);
std::istringstream input(line);
std::string word;
std::vector<int> output;
while (input >> word) {
try {
int i = std::stoi(word);
output.push_back(i);
}
catch (...) {}
}
For example, given input like: "123a456 321 1111233423432434342343223344 9", this will read in [123, 321, 9].
Of course, I'm just taking a guess about your requirements, and I haven't worked at making this particularly clean or elegant--just a straightforward implementation of one possible set of requirements.
Please see the comments from #LearningC and #M.M.
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>
using std::cout;
using std::cin;
using std::vector;
using std::string;
using std::istringstream;
int main()
{
vector <int> arr;
string buf;
int input;
cout << "Enter the elements of the array: \n";
getline(cin, buf);
istringstream ssin(buf);
while(ssin >> input)
{
arr.push_back(input);
}
cout << "The array: \n";
for(size_t i = 0; i < arr.size(); i++)
{
cout << arr[i] << " ";
}
return 0;
}
I am currently trying to write a text based RPG. I am working on the user input and how they will choose their actions. I am attempting to take each word from a sentence that the user inputs and put them each separately into an array. That way it can analyze each word and know what the user is attempting to do. I cannot seem to figure out how to go about doing that. I have been looking all around the internet but no one seems to have the same problem as I do. Theres nothing wrong with my code I just cant seem to figure out how.
Here is an example:
#include<iostream>
#include<string>
int main () {
string input [arrayLength];
int arrayLength;
std::cout<<"You are in a mysterious place and you see a creepy man. You don't know where you are. What do you do?"<< std::endl;
//In this case you could either type "run" , "ask man location" , "fight man".
}
I want the user to be able to type any of these commands at any time and then set the variable arrayLength to how many words there are, and then put each word into the array.
How would I do this?
You can use std::istringstream to easily extract the individual words from the input string.
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
int main()
{
std::cout << "You are in a mysterious place and you see a creepy man.\n";
std::cout << "You don't know where you are. What do you do?" << std::endl;
// Get input from the user
std::string line;
std::getline(std::cin, line);
// Extract the words
std::istringstream input(line);
std::string word;
std::vector<std::string> words;
while (input >> word)
words.push_back(word);
// Show them just for fun
for (auto&& word : words)
std::cout << word << '\n';
}
This will wait for the user to enter a complete line before processing it. This is important since std::cin by default treats newline characters as whitespaces during stream operations and will skip them.
Our professor gave us this assignment, where we have a .txt file with the following format:
John 23
Mary 56
Kyle 99
Gary 100
...etc. etc.
What we have to do is read the file, and store the names and scores in parallel arrays.
This is turning out to be a bit more challenging to me than I anticipated. What is confusing me, when searching around stack, is all the different libraries people use to do this. Our Prof just wants us to use string, fstream, and sstream to do this.
Below is what I've come up with so far, it compiles perfectly, splits the scores from the names but stores them in the same array:
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
const int SIZE = 50;
string names[SIZE];
int score [SIZE];
short loop = 0;
string line;
ifstream inFile("winners.txt");
if (inFile.is_open())
{
while(!inFile.eof())
{
istream& getline(inFile >> line);
names[loop] = line;
cout << names[loop] << endl;
loop++;
}
inFile.close();
}
else cout << "Can't open the file" << endl;
return 0;
}
I'm not looking for someone to solve my HW problem, I just want a push in the right direction!
If you want to read two things for each line of input, it seems reasonable to have two "read" statements:
std::string name;
inFile >> name;
int score;
inFile >> score;
std::cout << "Read score " << score << " for name " << name << '\n';
...then you can do that repeatedly until you've read the entire file.
Edit: After you get the basic logic worked out, you might want to think about error handling. For example, what is appropriate behavior for your program if the input file doesn't contain 50 pairs of (name, score)? How can you change your code to get that behavior?
Each line in the file consists of a name and a score separated by whitespace. You're reading each line but not splitting it into its parts (the name and the score).
Ideally you would use a vector for this, but since it seems that you were asked to use arrays we'll stick with arrays. What you have above looks good until you start reading entries. A more idiomatic way to accomplish this is to use std::getline, i.e.
ifstream inFile( "winners.txt" );
std::string line;
while( std::getline( inFile, line )) {
// Do work here.
}
Inside the loop you need to split the line on the space. Without solving the problem for you, I suggest you take a look at the find and substr functions of the string class: here. They will give you everything you need to solve the problem.
I'm trying to use safe practices in handling input with numbers only in C++, so I use a stringstream object as so:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
int first, second;
string input;
stringstream sstream;
cout << "First integer: ";
getline(cin, input);
sstream.str(input);
sstream >> first;
cout << first << endl; //display user input in integers
cout << "Second integer: ";
getline(cin, input);
sstream.str(input);
sstream >> second;
cout << second << endl; //display user input in integers
getline(cin, input); //pause program
return 0;
}
However, the second time around it seems to give the variable 'second' an arbitrary value. This is the output:
First integer: 1
1
Second integer: 2
2293592
If I declare two stringstream objects and use them respectively for both variables it seems to work fine. Does this mean that I cannot re-use a stringstream object in the way I'm trying to do? In my real program I intend to handle much more than two input values from the user, so I just want to make sure if there's another way instead of making multiple stringstream objects. I doubt it's of great relevance but I'm on Windows XP and I'm using MinGW as my compiler.
I greatly appreciate any help.
Use sstream.clear(); after sstream >> first;.
You need to reset the state of the stringstream. Generally, this involves two steps: clearing the buffer:
sstream.str("");
and resetting the error state flags:
sstream.clear();
If you don't clear the buffer, if you get an input like "123abc" then "abc" will still be in the stream when you try to read from it the next time.
You should also make sure to test the fail state of the stream (sstream.fail()) to ensure that the extraction was successful. If you want to be sure that the user only entered an integer (i.e., you want to prevent the user from inputting, say, "123abc", then you should test to make sure sstream.eof() is true.
A better way to do this conversion between datatypes would be to use boost::lexical_cast.
Info and examples can be found at the Boost Site.
Below is an example of doing an int to string conversion and back (string to int) such as what you're doing in your program.
#include <string>
#include <boost/lexcal_cast.hpp>
int main(int argc, char *argv[])
{
int i = 42;
std::string s = boost::lexical_cast<std::string>(i);
int j = boost::lexical_cast<int>(s);
return 1;
}
cout << "First integer: ";
getline(cin, input);
sstream.str(input);
sstream >> first; // state of sstream may be eof
cout << "Second integer: ";
getline(cin, input);
sstream.str(input);
sstream.clear(); // clear eof state
sstream >> second; // input from sstream
Okay, I was writing a simple C++ function to combine cin'd strings. I'm working on Linux at the moment, so I don't have the luxury of a simple "getline(cin, input)" command. Here's the code so far:
string getLine()
{
string dummy;
string retvalue;
do
{
cin << dummy;
retvalue += dummy;
} while
return retvalue;
}
What I want to know is this: is the prompt actually asking the user for input, or is it still reading from the buffer that was left over because of a space?
There is a getline defined for strings:
std::string line;
std::getline(std::cin, line);
I'm working on Linux at the moment, so I don't have the luxury of a simple "getline(cin, input)" command.
What's Linux got to do with it? getline is standard C++, except it's spelled cin.getline(input, size[, delimiter]).
Edit: Not deleting this because it's a useful reference, but AraK's post illustrating std::getline should be preferred for people who want a std::string. istream's getline works on a char * instead.
Yes. the prompt IS actually asking the user for input, but it is expecting a word rather than a line. That is possibly why it appeared space sensitive to you.
What you want, assuming you want to read more than one line, is this.
#include <iostream>
...
std::string sLine;
while(getline(std::cin, sLine)) {
// process sLine;
}
The code had a few other issues.
cin << dummy // this should have the >> operator
The variable should probably be called "word" not "dummy"
retvalue += dummy; // you would need to add spaces between words
} while // the while test should be some test for end of line
The loop in the question is closer to a word reader.
This would do for that objective.
#include <string>
#include <iostream>
#include <list>
...
void getStandardInput(std::list<std::string> & stringList) {
std::string word;
while (true) {
cin >> word;
if (cin.eof())
return;
stringList.push_back(word);
}
}
getline() is in the <string> header
I always forget that.