Using switch statement in Fibonacci sequence - c

Im currently writing a program which calculates the fibonacci number of a given integer using recursion. I created my own function 'fibonacci' and made the program to run on loops as you can see in the code.
The program wants me to use switch statement to operate the menu (The menu is the one where the user gets two options of either choosing to find fibonacci or to exit the program), and I am stuck on how to use switch statement in order to use the menu.
Here is the code I wrote so far
#include <stdio.h>
int fibonacci(int num);
int main(int argc, char const *argv[]) {
int choice;
int num;
int sequence;
printf("1) Calculate Fibonacci\n");
printf("2) Exit\n");
scanf("%d", &choice);
if (choice == 1)
{
do
{
printf("Input integer n :\n");
scanf("%d", &num);
if (num < 0)
{
printf("n should be a positive integer (n >= 1). Retry\n");
}
} while (num < 0);
}
if (choice == 1 && num > 0)
{
printf("Fibonacci sequence of %d terms\n", num);

From "The C Programming Language" by Kernighan and Ritchie:
"The switch statement is a multi-way decision that tests whether an expression matches one of a number of constant integer values, and branches accordingly."
So it should look similar to this:
while ((choice = getchar())!= EOF){
switch (choice){
case '1':
// calculate Fibonacci sequence
break;
case '2':
return 0;
}
}
As one of the comments suggests, either initialize your local variables in the beginning or check the return value of your getchar() or scanf() calls, since values of uninitialized variables are indeterminate.
If you've just started studying C, I suggest that you read the book that I mentioned. It's relatively short and has lots of helpful examples.

Related

Switch statement within a do...while loop(values stacking)

I am a student and just 4 weeks into programming and I hope I can get help here huehue. So I am making a program where you can translate decimal numbers into octal and binary and vice versa. The program continues to ask the user to choose until they choose letter d to exit the program. The program seems to run fine at first but when I tried to use again the same letter and input values, the output seems to stack from the output from the last time, not overwriting I guess(sorry if my terminologies or grammar is wrong, I am not that good in english)What do I need to change? I can't figur it out huhuhu.
#include<stdio.h>
#include<math.h>
int main(){
int c, k, r=0, e=0, dec=0, o=0, place=1;
long n;
char choice, new, d;
do{
printf("Choices:\na. Decimal to binary and octal\nb. Octal to decimal and binary\nd. Exit.\n\n");
printf("enter your choice:\t");
printf("\n");
scanf(" %c", &choice);
switch(choice){
case 'A':
case 'a':
printf("Conversion: Decimal to binary and octal.\n");
printf("Enter number:\n");
scanf("%ld", &n);
printf("%ld is ", n);
for (c =28; c >= 0; c--){
k = n >> c;
if (k & 1)
printf("1");
else
printf("0");
}
printf(" in Binary Form. \n");
printf("%ld is ", n);
while (n != 0)
{
o=o+(n%8)*place;
n=n/8;
place=place*10;
}
printf("%ld in Octal Form.\n\n", o);
break;
case 'b':
case 'B':
printf("Conversion: Octal to decimal and binary.\n");
printf("Enter number:\n");
scanf("%ld", &n);
printf("%ld is ", n);
for (c =28; c >= 0; c--)
{
k = n >> c;
if (k & 1)
printf("1");
else
printf("0");
}
printf(" in Binary Form.\n", n, k);
printf("%ld is ", n);
while(n!=0)
{
r=n%10;
dec=dec+r*(pow (8, e));
n=n/10;
e++;
}
printf("%ld in Decimal Form.\n", dec);
default:
printf("Exit.\n\n");
break;
}
}while(choice == 'a'|| choice =='A'|| choice == 'b'|| choice =='B');
return 0;
}
If I run the program with choice 'a' and enter 12, it returns:
12 is 00000000000000000000000001100 in Binary Form.
12 is 14 in Octal Form.
and if I do it again:
12 is 00000000000000000000000001100 in Binary Form.
12 is 1414 in Octal Form.
This is what you should tell us that level of detail as part of the question.
The minimal(ish) fix is to move the variables you initialize into the loop:
int main() {
char choice;
do {
int c, k, r=0, e=0, dec=0, o=0, place=1;
long n;
char new, d;
...
I moved all the declarations even though only the ones that were initialized were required to be moved. This reduces the scope of variables which usually a good practice.
Here are some other suggestions:
Both your switch and the last while loop check for the same thing. If use a if-else if loop instead you can use break to exit the loop. The other option is set a done indicator variable and check that in the loop.
I would also normalize the choice variable, i.e. choice = tolower(choice) so you don't have to check both lower and upper cases.
Consider driving the i/o in the main loop, then call a function that returns data which the main loop then prints out.
Use functions to eliminate duplication (i.e. the binary algorithm should probably be a separate function).
The binary algorithm looks wrong, btw, why does it loop 29 times? You pass it a long which might be 64 bits (at least it is on my system).
You read (signed) long but don't deal with negative values. #WeatherVane.
Value you read, n, doesn't seem to be validated. Should be able to type 'a' for a decimal or octal value? Or 9 for an octal value? Related to that, scanf() can fail so check what it returns.
You say 'd' exits but program logic is anything but 'a' or 'b' (in lower or uppercase) exits.
Formatting matters to people reading your code, so fix the wrong indentation of for (c =28; c >= 0; c--){. I would also suggest you use tab (or 8 spaces). This will encourage you to minimize how many levels you indent your code.

Goto and Code Repetition - Are they avoidable in this case?

I've recently faced a programming problem, and it seems to me that the most optimized way of solving it is by using goto, even though it's not a good practice. The problem is: tell the user to enter a positive natural number ( > 0) and read the input. If this number is valid, tell the user the square of that number. Do this while the input is correct. I came up with a few solutions, but all of them seem to have problems. Here are two of them:
Solution 1 - Problem: Uses goto
#include <stdio.h>
int main()
{
int num;
_LOOP:
printf("Enter a positive natural number: ");
scanf("%i", &num);
if (num > 0) {
printf("Square: %i\n", num * num);
goto _LOOP;
}
printf("Invalid number\n");
return 0;
}
Solution 2 - Problem: Double-checks if num > 0 (code repetition)
#include <stdio.h>
int main()
{
int num;
do {
printf("Enter a positive natural number: ");
scanf("%i", &num);
if (num > 0)
printf("Square: %i\n", num * num);
} while (num > 0);
printf("Invalid number\n");
return 0;
}
Obviously, there are more ways to solve the problem, but all the other ones I came up with that do not use goto encouter the same code repetition problem. So, is there a solution where both goto and code repetitions are avoided? If not, which one should I go for?
Here's half the answer; try to fill in what's missing. Remember that sometimes it's better to structure your loop as "do something until..." rather than "do something while..."
for (;;) {
printf("Enter a positive natural number: ");
scanf("%i", &num);
if (num <= 0)
break;
printf("Square: %i\n", num * num);
}
printf("Invalid number\n");
[updated with #rdbo's answer]
What about breaking out of the loop? This is basically a goto statement to the end of the loop without explicitly using goto.
#include <stdio.h>
int main()
{
int num;
while(1) {
printf("Enter a positive natural number: ");
scanf("%i", &num);
if (num > 0) {
printf("Square: %i\n", num * num);
} else {
printf("Invalid number\n");
break;
}
}
return 0;
}
The other option: check a bool that stores if the continue condition is met. It reads much easier than the infinite loop/break approaches (to me) and there's no code repetition.
#include <stdio.h>
#include <stdbool.h>
int main()
{
int num;
bool bContinue;
do {
printf("Enter a positive natural number: ");
scanf("%i", &num);
if (num > 0){
printf("Square: %i\n", num * num);
bContinue = true;
}
else{
printf("Invalid number\n");
bContinue = false;
}
} while (bContinue);
return 0;
}
For starters if you expect a non-negative number then the variable num should have an unsigned integer type for example unsigned int.
As it is written in your question the user can enter an invalid data or interrupt the input. You have to process such a situation.
Also the multiplication num * num can result in an overflow.
And using goto instead of a loop is indeed a bad idea.
Pay attention to that you should declare variables in minimum scopes where they are used.
To use the for loop for such a task is also a bad idea. It is much expressive to use a while loop.
The program can look the following way
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
while ( true )
{
printf( "Enter a positive natural number: " );
unsigned int num;
if ( scanf( "%u", &num ) != 1 || num == 0 ) break;
printf( "Square: %llu\n", ( unsigned long long )num * num );
}
puts( "Invalid number" );
return 0;
}
The program output might look like
Enter a positive natural number: 100000000
Square: 10000000000000000
Enter a positive natural number: 0
Invalid number
Or it would be even better to move the last output statement inside the while statement. Fo rexample
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
while ( true )
{
printf( "Enter a positive natural number: " );
unsigned int num;
if ( scanf( "%u", &num ) != 1 || num == 0 )
{
puts( "Invalid number" );
break;
}
printf( "Square: %llu\n", ( unsigned long long )num * num );
}
return 0;
}
I am a bit surprised nobody suggested functional decomposition yet.
Instead of writing a big pile of primitive statements, cut main up into smaller functions.
Apart from readability/maintainability benefits, it also helps eliminate code duplication in a very natural way.
In OP's case, getting input from the end user is a separate responsibility, and makes a good choice for a separate function.
static bool user_enters_number(int *ptr_to_num)
{
printf("Enter a positive natural number: ");
return scanf("%i", ptr_to_num) == 1;
}
Notice user_enters_number explicitly tests the return value of scanf.
This improve end-of-file handling.
Likewise, you could give number validation its own function.
This may seem like overkill (it's just num > 0, right?), but it gives us the opportunity to combine the validation with the resulting error message.
Printing "Invalid number" at the end of main feels wrong. Invalid numbers are not the only exit condition; end-of-file is another.
So instead, I will let the validation function determine the message.
As a bonus, this makes it possible to support multiple error types (e.g. separate messages for negative numbers and for zero).
static bool is_valid_number(int num)
{
bool ok = (num > 0);
if (!ok) printf("Invalid number\n");
return ok;
}
We now have two boolean-typed functions that can be neatly chained together with && and put inside the condition part of a loop, which is an idiomatic way of saying: if either one of these functions fails (i.e. returns false), immediately exit the loop.
What's left, is a very clean main function.
int main(void)
{
int num;
while (user_enters_number(&num) && is_valid_number(num))
{
printf("Square: %i\n", num * num);
}
}
To appreciate the benefits in terms of maintainability, try rewriting this code so that it accepts two numbers and prints their product.
int main(void)
{
int num1, num2;
while (user_enters_number(&num1) && is_valid_number(num1) &&
user_enters_number(&num2) && is_valid_number(num2))
{
printf("Product: %i\n", num1 * num2);
}
}
The changes are trivial, and limited to a single function
(though you might consider adding a parameter input_prompt to user_enters_number).
There is no performance penalty for this 'divide-and-conquer' approach: a smart compiler will do whatever is necessary to optimize the code, e.g. inline the functions.

If statement inside while loop with the same condition

Is there a better way to write the following code by eliminating the repeated condition in the if statement in C?
while (n < 0) {
printf("Enter a positive integer: ");
scanf("%d", &n);
if (n < 0) {
printf("Error: please enter a positive integer\n");
}
}
Thank you.
Simply rework your loop breaking when correct input is given. This way the check is done only one time:
while (1)
{
printf("Enter a positive integer: ");
scanf("%d", &n);
if (n >= 0)
break;
printf("Error: please enter a positive integer\n");
}
And, as specified in comments, an optimized compiler should be able to reverse the loop by itself.
This is something that IMO is best accomplished with a bit of refactoring:
#include <stdio.h>
#include <stdbool.h>
static bool get_postive_integer(int *pOut) {
int n;
printf("Enter a positive integer: ");
scanf("%d", &n);
if(n < 0)
return false;
*pOut = n;
return true;
}
int main(void)
{
int n;
while (!get_postive_integer(&n)) {
printf("Error: please enter a positive integer\n");
}
}
Give the operation a name, check that it fails, and only then print a message accordingly. The success or failure condition is only coded once here, in the named operation.
You could use:
while (printf("Enter a positive integer: ") > 0 &&
scanf("%d", &n) == 1 &&
n < 0)
{
printf("Error: please enter a positive integer\n");
}
This stops if the printf() fails, if the scanf() fails, or if the value in n is non-negative. It's a good idea to always check that the scanf() succeeds. It is merely convenient that printf() returns the number of characters it wrote (or a negative number on failure) so it can be used in a condition too. You could add fflush(stdout) == 0 && into the stack of operations too.
Or you could decide that the code in the condition should be in a function:
static int read_positive_integer(void)
{
int value;
if (printf("Enter a positive integer: ") > 0 &&
fflush(stdout) == 0 &&
scanf("%d", &value) == 1 &&
value >= 0)
return value;
return -1;
}
and then the calling code is:
while ((n = read_positive_integer()) < 0)
printf("Error: please enter a positive integer\n");
There are many variations on the theme; you might wrap the while loop into a function; you might make the prompts into parameters to the function. You might decide to be more careful about reporting what goes wrong (different actions if printf() fails compared with what happens if scanf() returns 0 (non-numeric data in the input) or EOF (no more data in the input).
The following examples are presented in the spirit that people should know what is available in the language.1 The way I would usually write the code is shown in Frankie_C’s answer. As some have noted, optimization usually makes this simple case not worth worrying about, but the question is not limited to a simple evaluation like n < 0; the test might be a function call to some expensive evaluation of more complicated criteria.
Folks are not going to like this, but:
goto middle;
do
{
printf("Error, please enter a positive integer\n");
middle:
printf("Enter a positive integer: ");
scanf("%d", &n);
} while (n < 0);
If you are vehemently opposed to goto, you can use a stripped-down version of Duff’s device:
switch (0)
do
{
printf("Error, please enter a positive integer\n");
case 0:
printf("Enter a positive integer: ");
scanf("%d", &n);
} while (n < 0);
But you should not.
Footnote
1 Commonly, software engineers will have to work with code written by others, so they must be prepared to recognize and understand anything expressible in the language, even if that is just a first step toward rewriting it into better code. And occasionally situations arise where “ugly” code becomes desirable for commercial or other practical reasons.
Another alternative is to split into a function:
int func(){
int n;
printf("Enter a positive integer: ");
scanf("%d", &n);
return scanf("%d", &n) == 1 ? n : -1;
}
and the loop becomes
while ((n = func()) < 0){
printf("Error: please enter a positive integer\n");
}
although the assignment in the condition check is not to everyone's taste. Note that I return -1 if the return value of scanf is not 1, something that you should always check.
What I do though in this situation (See Eric's answer) is to write
switch (0) do {
printf("Error, please enter a positive integer\n");
case 0:
printf("Enter a positive integer: ");
scanf("%d", &n);
} while (n/*ToDo - make sure n is initialised if scanf fails*/ < 0);

Using getNum(); Properly and Infinite Loop Problems

Just having a few kinks in this assignment I'm trying to do. Basically I need to have a menu, 4 options, two of them accept input from user as the form of a base number and an exponent. The third one outputs the answer of the base raise to the power and then the fourth just exits the program.
I'm having trouble obtaining the users input via getNum(); I'm not too sure how to use it properly. Just looking on some tips on how to make my code work a little better.
Looking for Help:
Accepting user input from two different functions and using it to
output an answer
Working out the infinite loop problem when selecting menu option
Loop back program to main menu after each function is done and only
exit program when menu option 4 is selected
int main(void)
{
int option = 0;
do
{
loadMenu();
while (option<1 || option>4)
{
printf("\nChoose an option between 1 and 4:");
option = getNum();
while (getNum() != '\n');
}
switch (option)
{
case 1:
baseChange(); //Gets base number
break;
case 2:
powerChange(); //Gets exponent
break;
case 3:
calcMath(); //Calculates the answer
break;
default:
break;
}
}
while (option != 4);
printf("Goodbye!\n");
}
void loadMenu() //Menu choices
{
printf("Power Menu:\n" );
printf(" 1. Change base\n");
printf(" 2. Change exponent\n");
printf(" 3. Calculate\n");
printf(" 4. Exit\n");
printf("Option?\n");
}
int baseChange(int base)
{
printf("What is your base?: ");
base = getNum();
while (getNum() != '\n');
return base;
}
int powerChange(int power)
{
printf("What is the power?: ");
power = getNum();
while (getNum() != '\n');
return power;
}
int calcMath(int base, int power)
{
int index = 0;
long answer = 1.00;
for(index = 1; index <= power; index++) answer = answer * base;
{
printf("%d raised to the power of %d is %ld.\n\n", base, power, answer);
}
return answer;
}
I'm having trouble obtaining the users input via getNum(); I'm not too
sure how to use it properly.
You haven't told us anything about this function; it's not part of the C standard.
Just looking on some tips on how to make my code work a little better. Looking for Help:
I think it's a little early for that. Put more effort into solving your problems, and then come back if you have specific questions. More like this one:
Working out the infinite loop problem when selecting menu option
Look at what your program does with option the second time through the loop.
Please Declare the getnum() function before main() like below;
/* declare getnum() prior to its first use */
float getnum(void)
{
float x;
printf("Enter a number: ");
scanf("%f", &x);
return x;
}

C program to calc avg etc

i wrote this code in class today with the teacher helping me but I'm home now and need guidance, I'm not sure what i should do next to get it to compile atleast
the objective is to:
create a menu
enter a number(option A)
dispaly the average (option B)
display the highest and lowest number(option C and D)
display the total of all numbers entered(option E)
display the total amount of numbers entered(option F)
and quit(option G)
here is what i have so far, i apologies if its messy
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
//int getNumber (aNumber) {
// printf("Enter an integer between 0 and 1000.\n");
// scanf("%i", &aNumber);
// int result;
// }
char getMenuLetter();
int getNumber();
//declare variables
int aNumber = 0;
float avg = 0.0;
int high = -1;
int low = 1001;
int total = 0;
int count = 0;
char getChoice = 'x';
int main() {
//proptotype functions
do {
getChoice = getMenuLetter();
switch (getChoice)
case 'A':
aNumber = getNumber();
count++;
total += aNumber;
low = testLow(aNumber, low)
high = testHigh(aNumber, high);
break;
case 'B';
avg = (double) total/count; //display avg
printf("The average is %.2f", avg);
break;
case 'C':
high = getHigh();
printf("The highest value of all the numbers entered is %i.\n", high); //display highest number
break;
case 'D':
low = getLow;
printf("The lowest value of all the numbers entered is %i.\n", low); //displayer lowest value
break;
case 'E':
printf("The total of all the numbers entered is %i.\n", total);
break;
case 'F':
printf("The amount of numbers entered so far is %i.\n", count);
case 'G';
break: //end switch
} while (userChoice != 'G');
}
int testLow(int n) {
int result;
if (n < low)
result = n;
else
return 0;
} //End of main
char getMenuLetter() {
char result;
system("cls") //clear the screen.
printf("*************************************************\n");
printf("A) Enter a number between 0 and 1,000\n");
printf("B) Display the average\n");
printf("C) Display the highest value entered\n");
printf("D) Display the lowest value entered\n");
printf("E) Display the sum of all numbers\n");
printf("F) Display the count of all numbers entered\n");
printf("G) Quit the program\n");
printf("*************************************************\n");
scanf("%c", &result);
result =toupper(result);
///print f %c
//system pause
if (result != 'A' || result != 'B' || result !='C' || result !='D' || result !='E' || result != 'F' || result !='G'){
printf("You must enter A - G only! \n)");
system("pause");
} //end if
} while(result != 'A' || result != 'B' || result !='C' || result !='D' || result !='E' || result != 'F' || result !='G');
return result;
//end of GetMenuLetter
Here is what I suggest:
Compile your program first. Your compiler will return most of your errors (the important ones, at least).
Pay attention to your use of curly bases. In C (and in many other languages), the compiler will treat lines that follow other lines linearly. The curly braces cause a multidimensional interpretation. As a beginner to programming, you should practice using curly braces where you can, just so you get into the habit of segregating instructions. Also, you should pay close attention to matching your open curly braces with your closed curly braces. For more information, you should see the C Standard, 6.8: Statements and Blocks.
Your switch() block should end with a default: value, just in case you reach a choice that's unexpected.
I don't suggest putting your functions prototype inside your main() procedure. It has to do with scopes. Check this out, from Section 6.2.1 of the standard.
2 For each different entity that an identifier designates, the identifier
is visible (i.e., can be used) only within a region of program text
called its scope. Different entities designated by the same identifier
either have different scopes, or are in different name spaces. There
are four kinds of scopes: function, file, block, and function
prototype. (A function prototype is a declaration of a function that
declares the types of its parameters.)
I don't know what else to tell you. Try what I proposed in order. Make sure you read the standard though. As a final suggestion: try programming in a more ordered manner. Your code won't look so sloppy if you keep coding under the intent of wanting to make something you can read by the time you're finished.
Good luck.
Some hints:
Check your compiler errors and warnings beginning with the first.
Switch on additional warnings of your compiler (e.g. parameters -W -Wall for gcc).
There is a significant difference between ";" and ":" in C.
The body of a switch statement has to be enclosed in curly braces.

Resources