I am writing a program that receives a series of double
values from the user and does stuff with them, in the form of 1.2 .2 -3
-> white-space de-limited values
At this point, it's already been validated that the string input
contains only digits, '.', ' ', and '-'.
The program below is an outline of what I would like to use for additional input validation.
It seems like the while(buffer >> test)
loop can be used for this, checking if EOF
was reached for validation. However, there are a couple cases I am unhappy about.
Why is the
bad()
bit not setting forinput1
and how can I check for an input of that type? I had thoughtbad()
would be set due to the read/write error.What is the role of whitespaces in the stream? Are they generally ignored? To me, it seems like the stream simply begins at its current position and attempts to read the type it is designated, ignoring white space. It can do without whitespaces if a negative follows a positive, see
input2
.Does it always hold true that a
double
orint
value that is being read to will be set to0
when the stream fails to convert?
#include<iostream>
#include <sstream>
using namespace std;
int main(){
string input0 = "1 2 3"; // Failed, EOF, 'test' retains correct value -> standard what I want
string input1 = "1 2 3-"; // Failed, EOF, 'test' set to 0 b/c conversion failed -> why is bad not set?, not what I want -> how do I check for this?
string input2 = "1 2-3"; // Failed, EOF, 'test', correct values -> weird behavior (would prefer this didn't occur)
string input3 = "1 2 -3 "; // Failed, EOF, correct values -> does what I want it to
string input4 = ".1 2---3 "; // Failed, buffer position 4, 'test' set to 0 -> does what I want it to
string input5 = ".1 2 3 "; // Failed, EOF, correct values -> does what I want
string input6 = ".1 2 --3 "; // Failed, buffer position 4, 'test' set to 0 -> does what I want
string input7 = ".1 - 2 3"; // Failed, buffer position 2, 'test set to 0 -> does what I want
istringstream buffer(input7);
double test = 0;
while (buffer >> test){
cout << "In loop" << endl;
cout << "Value of test: " << test << endl;
cout << "Buffer position: " << buffer.tellg() << endl;
}
cout << "Out of loop" << endl;
cout << test << endl;
if (buffer.good()) // no error flags set
cout << "Good" << endl;
if (buffer.bad()) // read/write error on i/o (integrity of stream lost) -> never set?
cout << "Bad" << endl;
if (buffer.fail()) // logical error on i/o (failure to convert) -> set on EOF
cout << "Failed" << endl;
if (buffer.eof()) // EOF reached on input op
cout << "EOF" << endl;
// .clear() would clear stream
}
- Is there any way to check explicitly for inputs of type
input1
(most important),input2
,input7
andinput5
using stream functionality (and not another form of validation), in order to attempt to disallow them?