简体   繁体   中英

std::cin in an Array

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

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.

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.

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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM