Reputation:
I am a CS student trying to grasp some C++ basic concepts. I am trying to get the input of a user from std::cin and put it to an array.
example :
Input > ab ba cd[Entey key pressed] then I would like the array to contain [ab][ba][cd].
So far I have :
#include <iostream>
#include <string>
int main(int argc, char** argv)
{
std::cout << "Please give all strings seperated with white space (eg. ab ba cd) : ";
std::string input[12];
int i=0;
while(std::cin >> input[i])
{
if(input[i].compare("\n")) break;
i++;
}
//This will print contents of input[].
for(int k = 0 ; k < 12 ; k++)
{
std::cout << "input[" << k << "] = " << input[k] << std::endl;
}
return 0;
}
But unfortunately this only stores the first string (in this example "ab") in the first index of the array.
If I comment out the if(input[i].compare("\n")) break; a Segmentation fault will be produced. I guess because I exceed the memory allocated for the array and write in a place i shouldnt.
From what I understand so far std::cin will first put ab in input[0] of the array, and keep the remaining string [ba cd] in the stream, then on the next loop (after i++) [ba cd] will still be in the stream, cin will not read further from the keyboard (since something is on the stream) and it should put the string ba on input[1], etc. Please correct me if I am wrong.
Note : This is not homework. My course starts in about 1 month. Any help greatly appreciated. Thanks in advance
Upvotes: 1
Views: 10255
Reputation: 9172
std::string::compare does not return a boolean value -- it returns an int. This is used for sorting strings. It will return <0 if the left string is less, >0 if the right string is less, and 0 if they are the same. 0 is the same as boolean false, so your if statement is actually breaking whenever the string is NOT "\n" -- which is why you break out of the loop on the first iteration.
Also, cin will not give you the newline character -- so checking for "\n" will not work. Using getline will help you here.
This page is very useful for using cin/cout, istream/ostream, istringstream/ostringstream: http://www.cplusplus.com/reference/iostream/istream/
I keep it in my bookmarks, and use it periodically.
So, here's probably what you want to do:
#include <sstream>
std::string line;
getline(std::cin, line); // get the entire line
// parse each string from the line
std::istringstream stream(line);
for (int i=0; stream.good(); i++) {
stream >> input[i];
}
Note that you should also try to allow more than 12 input strings without crashing, which can be done with a vector:
// parse each string from the line
std::vector< std::string > input;
std::istringstream stream(line);
while (stream.good())
{
std::string temp;
stream >> temp;
input.push_back(temp);
}
The vector will dynamically grow as you add new strings to it. It's kind of like a "smarter" array in that sense -- you don't need to know it's full size at the start. You can build it up a piece at a time.
Upvotes: 6
Reputation: 1412
Use std::vector
.
std::string tmp_str;
std::vector<std::string> input_array;
while(std::cin.peek() != '\n' && std::cin >> tmp_str) {
input_array.push_back(tmp_str);
}
Upvotes: 2
Reputation: 12212
One obvious problem you could have with that code is that spaces are taken as delimitiers, so probably you're not going to obtain the desired behaviour.
#include <iomanip>
...
cin << ws;
... before reading anything. This will probably eliminate the problem with whitespaces, though, I would prefer to read the string in other way:
#include <utility>
#include <string>
...
string str;
getline( cin, str );
This way, you'll never have the problem of buffer overrum with your vector.
Upvotes: 3