Thread: Is it OK to use goto in this case?

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Mar 2016
    Posts
    203
    Yes, you're both right; peek() seems to be more accurate in this case. Thanks

  2. #2
    Nasal Demon Xupicor's Avatar
    Join Date
    Sep 2010
    Location
    Poland
    Posts
    179
    Problem with the operators is that if you've got 123abc, it's going to extract 123 and succeed
    That's an obvious problem, but my logic checked for that, so you could do:
    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.
    Or even:
    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? ");
    And yes, that's pretty much exactly how I checked it.
    Last edited by Xupicor; 10-19-2016 at 09:32 AM.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by whiteflags
    Then Elysia is definitely correct, in order for this to work in a rational fashion, you need to peek:
    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:
    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, "");
    }
    would result in:
    Code:
    Test #1: Correct input
    Test #2: Incorrect input
    Test #3: Incorrect input
    Test #4: Incorrect input
    which is what we would expect from a correct parse and validation.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    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");
    }

  5. #5
    CIS and business major
    Join Date
    Aug 2002
    Posts
    287
    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.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It's funny since C pretty much mandates the use of goto due to lack of RAII mechanisms.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by Elysia View Post
    It's funny since C pretty much mandates the use of goto due to lack of RAII mechanisms.
    You can put malloc() and free() in separate functions, enabling you to call them where necessary.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    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.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    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.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    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.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by Elysia
    However, doing it without [goto] probably going to make the code harder to read, write and maintain.
    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.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    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.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    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.
    Last edited by whiteflags; 10-29-2016 at 06:02 PM.

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by whiteflags
    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.
    (...)
    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.

    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.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    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.

    Quote Originally Posted by laserlight
    RAII, despite the name, isn't really about constructors, so your comment about constructors is a red herring.
    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.
    Last edited by whiteflags; 10-30-2016 at 12:47 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 0
    Last Post: 03-09-2016, 03:58 PM
  2. Upper case= lower case
    By ashley1nonly in forum C Programming
    Replies: 0
    Last Post: 02-18-2015, 10:24 PM
  3. Replies: 11
    Last Post: 01-23-2014, 06:25 PM
  4. Replies: 11
    Last Post: 08-25-2008, 12:01 PM
  5. upper case to lower case problem
    By Jasonymk in forum C++ Programming
    Replies: 3
    Last Post: 04-27-2003, 05:35 AM

Tags for this Thread