Feis.
I am actually not interested whether such a function catches bad input or not. I am interested if you know what's going on. If you do, you'll be able to make any function you want. I am not stopping you from making a function that accepts "bad input" as well. E.g.
" -5 "
Now let's see what presents you brought me.
Code:
if( !InStream )
{
//Oops, empty string found. That's not an integer either.
return false;
}
This comment is wrong actually. Even misleading. Just like the "bool variable issue"...
Code:
bool bNonDigit = false;
bNonDigit = false;
... you should have removed (or improved) this red comment as well.
Testing for (!InStream ), is the same as (!nstream.good() ).
Why could a stream not be in a good state? Let's see:
- A file could be corrupt.
- A file could be missing.
- A file could be locked.
- The memory contents could be corrupt.
- A hardware failure in general.
- The network doesn't work.
- There is nothing to stream, yet a stream extraction is forced.
This is what happened in my original code:
Code:
istringstream InStream( sInLine );
InStream >> dest;
if( !InStream )
{
//Oops, empty string found. That's not an integer either.
return false;
}
In this very code, two reasons are obvious: no stream is given (an empty string found), or something is wrong with the RAM in the computer. Perhaps more things could be wrong. Use your imagination.
So a more proper comment should have been:
//Stream no good: perhaps empty string passed to this function?
So you missed this one. No problem. We are here to learn.
Let's see, what else do we got?
Quote:
|
I'm working on learning sstream, ...
|
The trick is knowing what to learn. I'll teach you 1 minor thing. That's all you need to know on short notice.
std::istringstream : basic in-memory formatting
Let's write some simple code. Three lines, and everybody knows what's going on basically:
Code:
cout<<"Please enter a word. Then press <enter> "<<endl;
string TheWord;
cin>>TheWord;
If you understand this, then you will understand the rest!
Ok, so a std::string variable (=object!) will hold a string. For example the word 'Hello'.
How did this variable got the word in the first place?
1). Well, the word was in memory when the user pressed <enter>.
2) the std::cin operator extracted it from the memory and placed it in "TheWord".
FROM memory TO variable.
Or better:
FROM stream TO variable.
That's all.
Now let's look at
stringstreams, especially the std::istringstream stringstream.
This time we need only 1 line of code:
Code:
std::string TheString;
Then somehow, this variable gets a string. We don't care how. I'll give two options:
Code:
std:: string TheString;
std::cin>>TheString; //Option 1!
TheString = "5"; //Option 2!
Whatever, take your pick

.
Now we want some advanced formatting done. It reads like it is complicated but not if you realize that we have a special thing to load the string in a stream and then do with it whatever we want! That special thing is called a
stringstream. So let's load our string in a stringstream object:
Code:
std:: string TheString;
TheString = "5"; //Option 2!
std::istringstream MyIStream(TheString);
Now we have a stringstream object
MyIStream. It holds the unformatted (raw) data of TheString. We can do whatever we want with it. Since it holds a '5' (IT IS NOT A STD::STRING, BUT A STREAM!). That's right, you can use the istringstream object as if it is a normal stream, like you would encounter when pressing <enter> to input some data!
So lets use this stream:
Code:
std:: string TheString;
TheString = "5";
std::istringstream MyIStream(TheString);
int MyInt;
MyIStream >> MyInt; //As if: cin >> MyInt
Have you read the comment? Just like
cin >> MyInt, BUT this time the stream is coming from a stringstream instead of a standard output!
MyInt holds the number 5 now. Once again a few lines of code to show you what they have in common:
Code:
int MyInt;
cin >> MyInt; //User enters data to std stream. Std stream puts it in variable.
string TheString = "5";
istringstream IS(TheString); //Insert data in a different kind of stream.
IS >> MyInt; //Stringstream puts it in a variable.
A Must-Know Feature About (any) Stream
Suppose you do this:
And the users types first 10 spaces, and then the number and then types <enter>... would this be valid?
The answer is YES!. Why?
Because extractor operators (FROM stream TO variable = EXTRACTION) ignore whitespaces. A space is a whitespace. So suppose a users enters a load of bull after the number he should have entered:
Code:
std::cout<<"Please give me the number 5 man!"<<endl;
int MyFiveInt;
std::cin >> MyFiveInt;
And now the user types this (without the double quotes!) :
Then any stream, like
std::cin or
std::istringstream will:
1) Ignore the first 3 spaces.
2) Extract 5 to the variable.
3) ignore the following 2 spaces.
4) And leave "qwerty" as trash in the stream buffer.
So here is your major hint!
Now we are going to build up an efficient function to bit by bit:
Make a function that accepts a std::string, and TRIES to convert it into a an int. If it fails to convert then we don't care.
So:
1)
" 5 " //good!
2)
" -5" //good!
3)
" -5 ajfadfa" //good! But trash is left. We don't care.
4)
"f5" //fail! but we don't care.
5)
" f -5 5" //fail! but we don't care.
Do this first. Keep it simple. We will build up bit by bit!