Thread: simple while loop

  1. #1
    Registered User
    Join Date
    Feb 2008
    Posts
    1

    simple while loop

    Hi there

    I am writing a simple while loop which terminates on the condition that a certain value is found, as follows


    Code:
    std::string question = q.quest().que();
                std::string answer = q.ans().answer();
                std::string graphic = q.inf().info();
                std::string english1;
                std::string english2;
                std::string arabic1;
                std::string arabic2;
               
                
                while((answer != english1) || (answer != english2)) { 
                           random_shuffle(opt.begin(),opt.end()); 
                                english1 = opt[0].english();
                                arabic1 = opt[0].arabic();
                                english2 = opt[1].english();
                                arabic2 = opt[1].arabic();
                }


    The program gets stuck in the while loop. I guess this is some sort of error in the while loops condition. If I take out the second condition and make it just based upon “English1”, then it works fine.

    Any help?

    Thanks in advance

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    This is a common beginner mistake. conditions where "x != a || x != b" are always true unless a and b are actually the same thing. You probably want "x != a && x != b".

    Here's some more detail:
    if we have an expression like
    "x != a || x != b"

    If x == a, then the first part is false, but the second part is true because x is NOT equal to b when it is equal to a.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Examine this carefully:
    ((answer != english1) || (answer != english2))

    Assume that english1 != english2.
    Assume also that there exists a string x such that x != english1 and x != english2.

    Let answer = english1. Then answer != english2.
    false || true = true, so the loop keeps on running.

    Let answer = english2. Then answer != english1.
    true || false = true, so the loop keeps on running.

    Let answer = x. Then answer != english1 and answer != english2.
    true || true = true, so the loop keeps on running.

    So, the loop always runs regards of the input, i.e., it is a uncontrolled infinite loop.

    What you probably want to do is to change the || to &&.
    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
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Also, what if answer is not contained in opt at all?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    That's why I always avoid multiple conditions in a loop. I always use an infinite loop and breaks instead. It's easier to read and grasp. Well, that's my 3 cents.
    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.

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    That would change absolutely nothing. Except that it would make the code less understandable for every other programmer in the world.

    This is one habit of yours I really ask you not to pass on to newbies.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    And how does it make it less understandable?
    It makes it more understandable since you can read the body and see when it breaks instead of trying to figure out the complex loop conditions.
    This is a very good example why I typically do this. Loop conditions that are complex are error prone and hard to read.
    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.

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It removes the loop condition from the head of the loop, thus making the loop as a whole harder to understand. (This applies to all breaks within the loop, by the way, not just those in an infinite one.)

    I see no problem with complex loop conditions, as long as they're properly formatted.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Not from my point of understanding. If you could understand the loop conditions in the head, then you should understand breaks in the loop body.
    And those in the body are more straight forward to understand, since it's "if str is equal to x then break, if str2 is equal to y break" instead of "while x is not equal to x and y is not equal y loop".
    Not only more straight forward, because you don't have to worry about the OR or AND, but it separates them on more lines instead of one long condition and it shows a straight condition for when the loop will break.
    Well, anyway. You can't force someone to choose a style, so go with whatever is best.
    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.

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    If you could understand the loop conditions in the head, then you should understand breaks in the loop body.
    It's about visibility, not understandability.

    Separating on lines can be done with a condition. And I prefer stay-in-loop instead of break-out-of-loop conditions. I guess it stems from the way I think about loops. I want a loop condition to tell me under what condition the loop runs, not when it stops running.

    Of course, your method, being the atypical case, will also play less nicely with whatever optimizations the compiler thinks it can apply to the loop.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by CornedBee View Post
    It's about visibility, not understandability.

    Separating on lines can be done with a condition. And I prefer stay-in-loop instead of break-out-of-loop conditions. I guess it stems from the way I think about loops. I want a loop condition to tell me under what condition the loop runs, not when it stops running.
    But that is also easily fixed. You could easily try to put all conditions at a certain point of the loop and mark them with comments or you could place them at several points if need be and place comments there so it's easily spotted.
    I also believe it has an advantage to be able to stop the loop if something "bad" happens (like it encounters a NULL pointer where it expects a valid one). IF you would use loop conditions, you may more easily be confused when it breaks because it won't follow the loop conditions as stated in the header.

    Of course, your method, being the atypical case, will also play less nicely with whatever optimizations the compiler thinks it can apply to the loop.
    It's the downside, I guess. But unless it's really time consuming, you could get away with it. With heavy optimizations, the code becomes less readable anyway.
    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.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    It's the downside, I guess. But unless it's really time consuming, you could get away with it. With heavy optimizations, the code becomes less readable anyway.
    Right, we're talking about compiler generated optimizations, not "re-arrange and generally molest the source-code to make it more optimized" - so most people wouldn't care the least bit about what the compiler does, and thus what does affect things are:
    1. The overall ease of reading the code.
    2. The compilers ability to optimize the code.

    I think there are many arguments for either side of this, and I'm not going to try to solve your disagreement - it's a "style decision", and like so many style things, there's not one RIGHT and one WRONG way to do things - there are ways that you like and there are ways you don't like.

    On big loops, it can get very complicated to see where the loop ends if you have multiple exit points - this is also what can confuse the compiler in such cases - it may not be able to for example unroll the loop quite as well, or keep things in registers, for example. In "a few lines of loop", then it makes less difference for us humans, but perhaps even more sensitive to compiler "not realizing what's actually going on".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    On a side note,

    free2rhyme2k, this problem arises I think because of spoken language. At least that's how I solved it on my early days of programming. As noted before it's a common mistake and derives from the fact we usually erroneously employ 'or' and 'and' in the spoken language under many circumstances.

    Don't "speak" a conditional expression to yourself to test its validity. Instead have always present in your mind the truth tables, for OR and AND particularly. In short, always evaluate logical expressions mathematically, not verbally.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  14. #14
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by Elysia View Post
    But that is also easily fixed. You could easily try to put all conditions at a certain point of the loop
    Such as the head?

    I also believe it has an advantage to be able to stop the loop if something "bad" happens (like it encounters a NULL pointer where it expects a valid one).
    No, that's for asserts and perhaps exception handling if it's more than a sanity check.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by CornedBee View Post
    Such as the head?
    Such as the body

    No, that's for asserts and perhaps exception handling if it's more than a sanity check.
    Not always. I'd rather a program keeps executing and displaying an error instead of crashing.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. loop needed also how to make input use letters
    By LoRdHSV1991 in forum C Programming
    Replies: 3
    Last Post: 01-13-2006, 05:39 AM
  2. Trying to figure out a simple loop....
    By chadsxe in forum C++ Programming
    Replies: 9
    Last Post: 01-05-2006, 01:31 PM
  3. simple collision detection problems
    By Mr_Jack in forum Game Programming
    Replies: 0
    Last Post: 03-31-2004, 04:59 PM
  4. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  5. for loop or while loop
    By slamit93 in forum C++ Programming
    Replies: 3
    Last Post: 05-07-2002, 04:13 AM