C/Basic looping
Expert: Joseph Moore - 7/10/2009
QuestionI just began learning C today, and in my first attempt to create a simple
command line utility I find my program terminating instead of looping... After
the user enters a number 1-20 I would like them to be able to enter another.
How do I do this? Here is the simple code...
#include <stdio.h>
int main()
{
int twenty_facts;
printf( "Enter any number 1-20: " );
scanf( "%d", &twenty_facts );
if (twenty_facts == 1) {
printf ("Shrimp’s hearts are in their heads.\n");
}
if (twenty_facts == 2) {
printf ("When you die your hair still grows for a couple of
months.\n");
}
if (twenty_facts == 3) {
printf( "The King of Hearts is the only one without a moustache.\n"
);
}
if (twenty_facts == 4) {
printf("Desserts is stressed spelt backwards.\n");
}
if (twenty_facts == 5) {
printf("A lion’s roar can be heard from five miles away\n");
}
if (twenty_facts == 6) {
printf("Children grow faster in the springtime.\n");
}
if (twenty_facts == 7) {
printf("The elephant is the only animal with four knees.\n");
}
if (twenty_facts == 8) {
printf("The average human eats eight spiders in their lifetime.\n");
}
if (twenty_facts == 9) {
printf("If you keep a goldfish in a dark room it will turn white.\n");
}
if (twenty_facts == 10) {
printf("The dot over the letter “i” is called a tittle.\n");
}
if (twenty_facts == 10) {
printf("Donald duck was banned from Finland because he doesn’t
wear pants.\n");
}
if (twenty_facts == 11) {
printf("Chewing gum while you peel onions will stop you from
crying.\n");
}
if (twenty_facts == 12) {
printf("Bats always turn left when exiting a cave.\n");
}
if (twenty_facts == 13) {
printf("The world’s youngest parents were eight and nine and lived
in china in 1910.\n");
}
if (twenty_facts == 14) {
printf("The youngest Pope was eleven years old.\n");
}
if (twenty_facts == 15) {
printf("Starfish don’t have brains.\n");
}
if (twenty_facts == 16) {
printf("A pregnant goldfish is called a twit.\n");
}
if (twenty_facts == 17) {
printf("Jaguars are afraid of dogs.\n");
}
if (twenty_facts == 18) {
printf("An ostrich’s eye is bigger than its brain.\n");
}
if (twenty_facts == 19) {
printf("The first couple to be shown in bed together on prime time
TV were Fred and Wilma Flintstone.\n");
}
if (twenty_facts == 20) {
printf("A man called Charles Osborne had hiccups for 69 years!\n");
}
if (twenty_facts > 20) {
printf("I'm sorry, but that number is outside of the designated
parameters.\n");
}
getchar();
return(0);
}
/*Hope this is easy to understand, I just want it to keep going until the user
specifies they want to terminate it! Thanks! */
AnswerHi, Derek.
There are a few ways to accomplish this, really. First, I'll give you a brief rundown of loop types. Please note that when I put "// body", that I am just pointing out where the body of the loop, or the code that is executed within the loop, goes. It's purely a convenient shorthand.
First, there's the simple while loop. The format of the while loop is:
while (condition)
{
// body
}
The condition portion of the while loop is basically anything that equates to a true or false. One important thing to remember in C++ is that false is 0, and true is any non-zero value (usually, though some compilers do explicitly state that 1 is true). This means that you can use a number or similar as a condition in a while loop, something like:
int myLoopVar = 5;
while (myLoopVar)
{
// body
--myLoopVar;
}
In the above block of code, the loop will execute 5 times. It's more proper to actually have the condition evaluate to a boolean in order to catch cases when compilers do not consider any non-zero to be true, but few people actually do this (in my experience) because most compilers do consider any non-zero to be true. If you want the above code to be a bit more proper, you could write it as:
int myLoopVar = 5;
while (myLoopVar > 0)
{
// body
--myLoopVar;
}
Remember that in a while loop, the condition is checked before anything in the body of the loop is executed. That means that it is possible to never execute the code inside the while loop, if the condition is not met.
The next type of loop is the do-while loop. A do-while loop is basically a while loop where the condition checking occurs at the end of the loop instead of the beginning of the loop. This means that the code inside the do-while loop is guaranteed to execute at least once. I can honestly say that the do-while loop is the least-used loop type in C++, but there are circumstances in which the do-while loop makes code considerably cleaner. The do-while loop looks like:
do
{
// body
} while (condition);
The do-while loop really is exactly like a while loop outside of the point at which the condition is checked.
Finally, there is the for loop. The for loop is probably the most commonly used loop type. A while loop has its place, to be sure, but for loops are extraordinarily useful. A for loop looks like this:
for (initialization; condition; post-loop operation)
{
// body
}
Notice that there are three parts to a for loop. The for loop may have all, none, or anything in between of these sections defined. Generally all three are defined, such as the most common loop usage, iterating through a list:
int i;
for (i = 0; i < listSize; ++i)
The initialization section is used to set the initial value of any variables being used for loop parameters. The condition section is the condition that must be met for the loop to execute. The post-loop operation is a piece of code that is executed at the end of each loop cycle. The above loop would simply start at 0, verify that i is less than the size of the list, execute some code (assuming the condition was met), then increment i.
I haven't gone into all of the intricacies of each loop type, and I encourage you to research them further, but this is a good overview of the loops. One important thing to note is that, just like an if statement, there is no semicolon at the end of the line on a loop with one very important exception, which is the do-while loop.
Now, in your particular bit of code, I actually do recommend enclosing the whole thing in a do-while. You've inadvertently stumbled onto one of the best uses of a do-while loop: simply menu input. Rather than obtaining input, then looping in a while loop and writing the same input code inside the while loop, you can just write a do-while loop and write the input code inside the loop. This will look something like:
int twenty_facts;
printf( "Enter any number 1-20 (0 for quit): " );
scanf( "%d", &twenty_facts );
do
{
// giant if block
} while (twenty_facts != 0);
Also, just as a quick side note, your block of if statements could benefit from some improvement. Because each input is mutually exclusive, an if/else if/else block would be better. Basically, the user cannot input both 1 and 2, so if 1 is true, then there is no reason to test if 2 is true. Also, while you do check for > 20, you do not check for <= 0. In my proposed loop, 0 is actually valid input (used for quit), but negative numbers are still invalid.
Beyond the simply if/else if block, a switch statement is generally preferred. A switch statement is a slightly more advanced topic, though, so you may wish to wait until you have more experience with the language to really try that. I won't go into switch statements right now, but I do recommend researching them when you feel a bit more comfortable with the language.
If you have further questions or if anything I have said is unclear, please feel free to post a followup or simply ask me a new question.