Yes, you're both right; peek() seems to be more accurate in this case. Thanks
Printable View
Yes, you're both right; peek() seems to be more accurate in this case. Thanks
That's an obvious problem, but my logic checked for that, so you could do:Quote:
Problem with the operators is that if you've got 123abc, it's going to extract 123 and succeed
Or even:Code:idiot::io io;
int a;
io << "Provide integer: " >> a; // type in "231lasd" -> reaction: print default error message ask for value again, only return where proper value was given.
And yes, that's pretty much exactly how I checked it.Code:io << "Provide amount: " >> "[1..10]" >> set(a).when([](const auto& n){ return n >= 1 && n <= 10; }).on_error("Ya just can't help yourself, eh? ");
You can check for eof(). I don't quite understand why this is the case for stringstreams when normally we expect the end-of-file condition for other input streams to require a failed read, so it may be a non-standard peculiarity with the g++ standard library implementation across versions (and MSVC, though I don't remember for sure if I tried that one), but this:Quote:
Originally Posted by whiteflags
would result in:Code:#include <string>
#include <sstream>
#include <iostream>
using namespace std;
void test(int n, const std::string& input)
{
cout << "Test #" << n << ": ";
long choice = 0;
stringstream conv(input);
if (!(conv >> choice) || !conv.eof()) {
cout << "Incorrect input\n";
} else {
cout << "Correct input\n";
}
}
int main()
{
test(1, "1234");
test(2, "2x");
test(3, "x2");
test(4, "");
}
which is what we would expect from a correct parse and validation.Code:Test #1: Correct input
Test #2: Incorrect input
Test #3: Incorrect input
Test #4: Incorrect input
Here's an idea to make it (possibly) more portable. It also allows spaces after the number.
Code:#include <string>
#include <sstream>
#include <iostream>
using namespace std;
void test(int n, const std::string& input) {
cout << "Test #" << n << ": ";
long choice = 0;
stringstream conv(input + '\0');
char c;
if (!(conv >> choice) || !(conv >> c) || c)
cout << "Incorrect input\n";
else
cout << "Correct input\n";
}
int main() {
test(1, "1234");
test(2, "2x");
test(3, "x2");
test(4, "");
test(5, " 321");
test(6, " 321 ");
test(7, " 321 x");
}
To OP, goto should be used sparingly if ever. Using goto indicates that there is some flaw in your logic, and that goto can be replaced by some other method, although it would be more difficult to solve, such as maybe recursion. So using goto is just any easy way out of fixing up your program, and shouldn't be used unless needed. I just read the Kernighan and Ritchie C Programming book, the inventors of C, and they say you should rarely ever use goto.
It's funny since C pretty much mandates the use of goto due to lack of RAII mechanisms.
That doesn't make it that much better. Still have to call said functions to do cleanup and pass in all the info that needs cleanup.
It doesn't have to make it much better. You said lack of RAII support makes goto necessary, and it doesn't. I'm not going to listen to an argument about this. It isn't true that goto is necessary. That is all I wanted to say.
Just because I said "pretty much mandates" doesn't mean I said it was necessary. You can still do without goto. However, doing it without it probably going to make the code harder to read, write and maintain. That is all I wanted to say. I just did it in a sarcastic way to take a poke the language.
What crazy person gave you this idea? Constructors and destructors are essentially functions with return type void. It is reasonable, then, to write functions, make abstractions on malloc() and free() in C, like it is reasonable to make a constructor and destructor for objects in C++. They are in service to achieving the same goal.Quote:
Originally Posted by Elysia
No, the whole point is that the compiler calls the destructors automatically. You don't see the compiler generating magic functions calls to behind your back in C.
Well, whatever. Those magic functions are very limited. All they ever do is call other (default) constructors or destructors -- if you so much as need to call a different constructor, you must write your own. I still don't see how this means goto is mandated by anyone to achieve the same effect in C: that some function, magic or not, be called for cleanup. It's a completely wrong statement.
I would say that the goto for cleanup idiom is a way of organising cleanup following the Don't Repeat Yourself principle, and in so doing helps to maintain discipline (effectively: Single-Entry-Single-Exit) so as to avoid the error of not doing cleanup by returning too early. Abstracting cleanup into functions works in conjunction with this, i.e., they work on the granularity of an interface, whereas goto for cleanup works at the level of a variety of interfaces used in a function. The various cleanup function calls could still be bundled into a single function that is then called before each early return instead of using goto for cleanup, but I guess C programmers reason that if you are going to call then return each time, you might as well goto a central place that does the cleanup then return, since the local context will be available without having to pass it each time.Quote:
Originally Posted by whiteflags
RAII, despite the name, isn't really about constructors, so your comment about constructors is a red herring. Rather, it is a way of automating cleanup so as to avoid the error of not doing cleanup by returning without doing cleanup, and in this sense it achieves the same goal as the goto for cleanup idiom, and like how that idiom works in conjunction with specific cleanup functions, so does it work with the chaining of destructors. One difference is that the goto for cleanup idiom fails in the face of exceptions, though this may not be a concern in C, and another difference is that while the goto for cleanup idiom works, it is more susceptible to mistakes since in the end the user of the interfaces still needs to explicitly remember to do cleanup, and likewise should the cleanup function calls be moved to a single helper function to be called before each return.
Well, okay. It's clearer to me now why Elysia said what he said. I'm glad someone was able to clarify, even though he should do it.
Is it misleading? I thought I stated things clearly, but I will repeat myself here. Default destructors call other destructors and if you need to do anything different, write your own. In short, follow the rule of three. No mention of constructors this time, so I hope this clears up any bad thing I said. Unless I'm wrong about this also.Quote:
Originally Posted by laserlight