0

I am from C#, Java background trying to learn C++. The following is a snippet I found for reading values for a structure variable. Could not quite figure out what is being done or whether this is the standard way of reading a string structure member. Isn't there a more cleaner way to do this.

   string mystr;

   struct structdefn
   {
     string member;
     ...
   } mystruct[10];

   ...
   getline (cin,mystr);
   stringstream(mystr) >> mystruct[n].member;
1
  • Do you have any information as to how mystr and mystruct are defined? Commented Dec 21, 2010 at 22:43

3 Answers 3

4

That code uses a temporary stringstream fed with a line read from stdin to read the data into the struct member. Although there are some reasons for which you may be doing that (e.g. to check that the >> operator consumes the whole line), generally you could more simply do

cin >> mystruct[n].member;

As for the explanation of your code:

  • getline reads a whole line from cin (the standard input stream) and puts it into the string mystr;
  • a temporary object of type stringstream is then created; stringstreams are a particular type of streams which aren't fed from a file/socket/whatever, but from a string. In this case, the string is mystr, the line just read from the standard input;
  • on that temporary object is called the operator >>, which, in this context, is called the extraction operator1; it's work is to extract from the stream and convert the data that will be put in the variable on its right, in this case mystruct[n].member.

The simpler code I posted just uses the operator >> directly from the standard input stream (cin), thus avoiding the intermediate passage of the stringstream.


1. Although with integers it's the binary right shift operator (which it's its original meaning).

Sign up to request clarification or add additional context in comments.

5 Comments

Just so the OP knows, this will work, but reading from the stream this way will only read until it encounters a whitespace character. The getline will read until a newline (\n) is found. As you said, it depends on what s/he is trying extract from the stream.
@Will: what you say about getline is true, but notice that it's not used to feed directly mystruct[n].member, but it's feeding the stringstream, which then uses the same operator>> that would be used on cin. A difference in the two methods from the perspective of what is put in mystruct[n].member should arise only if is used an operator>> which do not stop reading at newlines (so it would go on reading on cin, while on the stringstream it would stop at the \n for EOF).
I thought that >> would stop at a newline since it is considered whitespace? Does it treat that differently?
@Will: we don't know the type of member: if it's a string the normal operator>> will stop at whitespace, but what if it's a user-defined type with a custom operator>> which do not care about newlines (e.g. an operator that reads multiple scalars to load data for a structure - for it the newline may just be a delimiter)? The two snippets in general will behave differently.
that's true, I hadn't thought of it that way, though the original question (I thought) was dealing only with string data; but you are definitely right on that - what if it's an object that overrides >>. It would most definitely depend on the implementation details at that point.
2

Assuming that mystr and mystruct[n].member are both std::string instances, I'm not sure why the stringstream is being used - you should be able to simply read directly into the member string.

#include <iostream>
#include <string>
// Assuming that mystruct[n].member is a std::string
std::getline ( std::cin, mystruct[n].member );

It would be more helpful to have the declaration of the mystruct structure.

EDIT: You can make use of the stringstream if the data you are reading and storing into the structure member is not the entire line of text. The extraction operator >> will extract a "word" at a time from the string, where whitespace delimits the "words" in the line of text. Example:

// Where the line of text is "123 abc pdq" ...
std::string s;
std::getline ( std::cin, s ); // s now contains: 123 abc pdq
std::stringstream ss ( s );
ss >> mystruct[n].member; // member will contain: 123

There are ways to change the behavior of the stream regarding how the whitespace is handled, but this is the most commonly used way of extracting parts of a string of text into other strings.

Comments

1

The std::stringstream class is useful for complex string formatting (think printf, but type-safe), and converting between strings and other types.

For example, where you would use Integer.parseInt in Java, you would use std::stringstream in C++.

int i;
std::stringstream("123") >> i;

If you don't need to do conversion, and you don't need to string formatting, then you probably don't need a stringstream.

1 Comment

It would also be useful if the data is whitespace-separated; s/he could use it to easily parse the line into "words".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.