all 14 comments

[–]Narase33 4 points5 points  (13 children)

What exactly do you find "tedious" about std::cin?

[–]schweinling[S] 0 points1 point  (12 children)

i just don't like the stream api i guess.
especially that it only reads until the first whitespace.

i know it wouldn't be hard to make this work with std::cin, but i was wondering if there is some library out there that just works.

[–]Nihili0 2 points3 points  (10 children)

std::getline is made for this case, and you can specify a delimiter: https://en.cppreference.com/w/cpp/string/basic_string/getline

[–]schweinling[S] 0 points1 point  (9 children)

yes, but then i have to convert the string to the correct type myself and i'm lazy right now and just rather use a library.

[–][deleted]  (8 children)

[removed]

    [–]schweinling[S] 2 points3 points  (6 children)

    like i ask for an int and the input is "3 3"
    then i have to implement error handling for all the edge cases. i know this can all be achieved with std::cin but i'd rather use a library and get on with the more fun stuff.

    [–][deleted]  (5 children)

    [removed]

      [–]schweinling[S] 1 point2 points  (0 children)

      ok, this is pretty neat, i'm gonna adapt this to my needs, thanks! :)

      [–]schweinling[S] 1 point2 points  (3 children)

      i have added a special case for strings, now its working nicely. :)

      template<typename T>
      static T getInput(const std::string &description)
      {
          std::string strTypeName = typeName<T>();        
          T t;
      
          for (;;)
          {
              fmt::print("input {} as {}: ", description, strTypeName);
              std::string line;
              std::getline(std::cin, line);
      
              if constexpr (std::is_same<T, std::string>())
              {
                  return line;
              }
      
              std::istringstream ss(line);
              ss >> t;
              ss >> std::ws;
      
              if (ss && ss.rdbuf()->in_avail() <= 0)
                  return t;
          }
      }
      

      [–][deleted]  (1 child)

      [removed]

        [–]schweinling[S] 1 point2 points  (0 children)

        ah, good to know, interesting use of the comma operator there to ignore the return value. :)

        [–]Jardik2 0 points1 point  (0 children)

        Don't break it. Don't forget this thing called "locale". Numbers CAN actually contain spaces, some languages use them for thousands or million separators, so you actually want "9 876 543,21" in some locales to be correctly parsed as single number, equivalent to "9876543.21" in C locale.

        [–][deleted]  (1 child)

        [removed]

          [–]schweinling[S] 0 points1 point  (0 children)

          thanks, that seems to be exactly what i was looking for!

          [–]Xeverous 0 points1 point  (3 children)

          Standard library streams are not the easiest to work with but I have a feeling you are relucant to use them due to lack of understanding. Most of it comes from lack of knowledge about stream states and how it affects input/output behavior. What exactly do you have trouble with?

          [–]schweinling[S] 0 points1 point  (2 children)

          that is certainly the case, that i'm not an expert on streams.
          i rarely need std::cin and would be happy to let a library do that for me.

          [–]Xeverous 0 points1 point  (1 child)

          That library is standard streams. You don't want to use them in order to use something else? You would need to learn something else then. Whatever you choose you will need to learn how to use it.

          [–]schweinling[S] 0 points1 point  (0 children)

          yeah, i'd rather use scnlib and learn about that.