0

In this tutorial, they say we should do this:

 #include <iostream>
 #include <string>
 #include <sstream>

 int main ()
 {
   std::string stringLength;
   float inches = 0;
   float yardage = 0;

   std::cout << "Enter number of inches: ";
   std::getline (std::cin,stringLength);
   std::stringstream(stringLength) >> inches;
   std::cout<<"You entered "<<inches<<"\n";
   yardage = inches/36;
   std::cout << "Yardage is " << yardage;
   return 0;
 }

However, this:

#include <iostream>
#include <string>
#include <sstream>

int main ()
{
    float inches = 0;
    float yardage;

    std::cout << "Enter number of inches: ";
    std::cin >> inches;
    std::cout<<"You entered "<<inches<<"\n";
    yardage = inches/36;
    std::cout << "Yardage is " << yardage<<"\n";

    return 0;
}

works for me.

However I'm a beginner so I guess there is something I'm missing but I can't see why. Some might say it's useful to keep the string stringLength so that I can handle cases where the user wouldn't input a float but rather abc, but I'm sure I could do it without using <sstream> (by checking character by character in stringLength if it's only digits or the character . for example). Or even like this:

#include <iostream>
#include <limits>

int main() {
    double inches;
    double yardage;

    while (true) {
        std::cout << "Enter inches: ";

        if (std::cin >> inches) {
            std::cout << "You entered " << inches << "\n";
            yardage = inches / 36;
            std::cout << "Yardage is " << yardage << "\n";
            break;
        } else {
            std::cout << "Invalid input. Trying again..." << std::endl;
            std::cin.clear(); // Clear the error state
            // Ignore the rest of the input buffer
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        }
    }

    return 0;
}

Yes indeed, sstream could mean I don't have to flush the input buffer, but is this really good enough to justify its use? Or am I missing something?

#include <iostream>
#include <sstream>

int main() {
    std::string stringLength;
    float inches;
    float yardage;


    while (true) {
        std::cout << "Enter inches: ";

        std::getline (std::cin,stringLength);
        if (std::stringstream(stringLength) >> inches){
            std::cout<<"You entered "<<inches<<"\n";
            yardage = inches/36;
            std::cout << "Yardage is " << yardage;
            break;
        }
        else {
            std::cout << "Invalid number, please try again\n";
        }

    }

    return 0;
}
  • The reasons are well explained in the duplicates answers. It's about `getline ()` won't work well in a loop alone if mixed with formatted text extraction. For your example it doesn't seem to be necessary. – πάντα ῥεῖ Jun 08 '23 at 16:19
  • 1
    I'm not sure I understand, I'm not prompting the user for two inputs in my code? – FluidMechanics Potential Flows Jun 08 '23 at 16:19
  • 1
    What if there's an error in the input, that you want to ignore? While it's possible while dealing with `std::cin` it's more complicated as you much flush the remaining line, and clear the failed state of `std::cin`. You can't just continue using `std::cin` as if nothing happened. – Some programmer dude Jun 08 '23 at 16:22
  • @Someprogrammerdude oh so the difference is with their solution, if there's an error i don't lose the original user's input and i can do something with it whilst for me, it's flushed? – FluidMechanics Potential Flows Jun 08 '23 at 16:23
  • 1
    The second code snippet implies that it's inside a loop. That loop will not work if the user inputs invalid input, not with the code as shown. If you use `std::getline` and an input string stream, you would not have to do any extra work if there's invalid input. – Some programmer dude Jun 08 '23 at 16:28
  • Oh it won't work because once `std::cin` fails to convert it ignores all the following `std::cin`? – FluidMechanics Potential Flows Jun 08 '23 at 16:30
  • @fluid Yup, that's how it behaves, and again everything is explained in detail in the duplicate. – πάντα ῥεῖ Jun 08 '23 at 16:33
  • I've edited my post to add something that would prevent this AND that would prove we don't need stringstream. Obviously I'm a beginner so I must have missed something, but I'm still confused. I did read the duplicate entirely and did not find answer to my question. – FluidMechanics Potential Flows Jun 08 '23 at 16:34
  • Yes that's correct! While it's possible to clear the fail status, and flush the reminder of the current line, it's much simpler to just continue the loop as if nothing happened, because the problems will be on the temporary string stream. :) – Some programmer dude Jun 08 '23 at 16:34
  • @Someprogrammerdude oh i see, so with stringstream (if i had a loop) i wouldn't have to flush anything? EDIT: yes it worked. Although I'm still not convinced of the use since we can flush it all... – FluidMechanics Potential Flows Jun 08 '23 at 16:35

0 Answers0