2

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.

  1. Why is the bad() bit not setting for input1 and how can I check for an input of that type? I had thought bad() would be set due to the read/write error.

  2. 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.

  3. Does it always hold true that a double or int value that is being read to will be set to 0 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
    
}
  1. Is there any way to check explicitly for inputs of type input1 (most important), input2, input7 and input5 using stream functionality (and not another form of validation), in order to attempt to disallow them?
user18348324
  • 244
  • 10
  • For question 3, see e.g. [this old answer of mine](https://stackoverflow.com/a/13379073/440558). Since the C++11 standard, zero will be written to the variable. – Some programmer dude Dec 28 '22 at 09:41
  • you cannot overload operator>> for double (or any operator for any built-in types, https://isocpp.org/wiki/faq/intrinsic-types#intrinsics-and-operator-overloading), but you could create your own class implement the behaviour of the operator>> as you wish and then convert the value to double. – Alessandro Teruzzi Dec 28 '22 at 10:10
  • The general algorithm is: Skip leading whitespace, then collect characters that *could* be part of a valid value, then try to convert the result (if any)". Here `eof` means nothing to collect, while `bad` means conversion failed. In your examples, a minus not followed by a digit is `bad`. – BoP Dec 28 '22 at 10:32
  • Then how come `bad` wasn't set @BoP ? I tried to make the tests easily reproducible, so you could see for yourself. – user18348324 Dec 28 '22 at 10:45

0 Answers0