简体   繁体   中英

Is is possible to stringstream this way? to convert from string to int?

Is it possible to stringstream like this? I am trying to read with ifstream and convert it.

string things = "10 11 12 -10";
int i1;
int i2;
int i3;
int i4;
stringstream into;
into << things;
into >> i1;
into >> i2;
into >> i3;
into >> i4;

I expect it to be :

i1 = 10
i2 = 11
i3 = 12
i4 = -10

is that correct?

Can the same stringstream variable be used multiple times?

When I tried, the first time was ok but everything else later on is just 0.

That should definitely work. You can even mix types, as shown below:

string things = "10 Nawaz 87.87 A";
int i;
std::string s;
float f;
char c;

stringstream into;
into << things;
into >> i >> s >> f >> c; //all are different types!

cout << i <<"  "<< s <<"  "<< f <<"  "<< c;

Output:

10 Nawaz 87.87 A

Demo at ideone : http://www.ideone.com/eb0dR

Does it work? The way I would do it is:

istringstream into(things);
into >> i1;

and so on. That would produce the output you posted.

What you posted works, along with Jeremiah Willcock's solution using istringstream instead. But consider using the scanf family of functions as well (for just a couple of ints it doesn't make much of a difference, but for more advanced input, using scanf can be much more concise than messing around with stream manipulators):

string things = "10 11 12 -10";
int i1, i2, i3, i4, i5, i6;
sscanf(things.c_str(), "%d %d %d %d", &i1, &i2, &i3, &i4);

The reason your example just gives 0's after that is because the stringstream buffer is empty once you extract the -10: you'll have to insert more into the buffer before you can extract more. You can use the same stringstream instance multiple times, but you'll either need to fully use the buffer each time, or realize that there's more in the buffer before the next item you insert into the buffer:

string things = "10 11 12 -10", temp;
int i1, i2, i3, i4;
stringstream into;
into << things; //buffer is now "10 11 12 -10"
into >> i1; //buffer is now " 11 12 -10"
into >> i2; //" 12 -10"
into >> i3; //" -10"
into >> i4; //""

//more code here...

//come back and use the instance again
into << "more: 1 2 3"; //"more: 1 2 3"
into >> temp; //temp is "more:"; into's buffer is " 1 2 3"
into >> i1; //buffer is " 2 3"

//more code here...

//reuse into once again
into << "4 5 6"; // buffer is now " 2 3 4 5 6"
into >> i1; //i1 gets the 2 from before, not the 4 just inserted; buffer now " 3 4 5 6"
into >> i2; //i2==3; buffer is " 4 5 6"

Also, ios (from which stringstream inherits) also defines the ! operator and a cast to void* so that you can conveniently check if extraction failed (technically checks if failbit or badbit is set, and I believe failbit is the one that gets set along with eofbit when there's not enough in the buffer):

string things = "10 11 12 -10";
int i1, i2, i3, i4;
stringstream into;
into << things;
into >> i1 >> i2 >> i3 >> i4;
if (into >> i5) {
    cout << "extraction to i5 succeeded" << endl;
}
if (!(into >> i6)) {
    cout << "extraction to i6 failed" << endl;
}

Yes it will work.
The only difference I would make is:

string things = "10 11 12 -10";
int i1;
int i2;
int i3;
int i4;

stringstream into(things);    // Initialize in the constructor
into >> i1 >> i2 >> i3 >> i4; // Chain the inputs.

Note the linestream is just like a normal stream and it will run out of items and set failure state when you read past its end.

stringstream into(things)
int val;
while(into >> val)                   // loop exits after 4 numbers as into.eof() 
{                                    // returns true after trying to read the 5 number.
    std::cout << "G(" << val << ")\n";
}

For example I like to do the following when reading multiple lines with 4 numbers:

std::string  line;
while(std::getline(std::cin, line))
{
    /*
     * This way if a line is formatted incorrectly (only 3 numbers)
     * The error is local to the line and we will pick it up in linestream
     * without affecting the scanning of subsequent lines
     */
    std::stringstream linestream(line);

    int i1,i2,i3,i4;
    linestream >> i1 >> i2 >> i3 >> i4;
}

As for your second question Can the same stringstream variable be used multiple times? ,
probably clear and seek of stream are needed before reuse.
For example, the following code will serve your second question:

int main() {
  string  s = "-1 2";
  stringstream  ss;
  ss << s;
  int i, j;
  ss >> i >> j;
  cout<< i <<' '<< j <<endl;
  ss.clear();
  ss.seekg( 0 );
  i = j = 0;
  ss >> i >> j;
  cout<< i <<' '<< j <<endl;
}

Hope this helps.

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