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

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.

Related

How to get summation in C?

How to make a program to read elements from input like:
1 3
and give me the summation of that:
4
#include <stdio.h>
int main(void){
char x[3];
scanf(" %c",&x);
printf("%d\n",x[0]+x[2]);
}
In your approach you seem to read in a string and treat several positions of that string as numbers. Besides the fact that there are several mistakes in implementing this approach, the main thing actually is that you've taken the wrong approach. Drawbacks (not all, just some) are: you only consider numbers of exactly one digit; you assume that user input is exactly mapped to your array with exactly one "blank" position between the numbers of interest (as you access x[0]+x[2] with hard-coded indexes 0 and 2); you are limited to exactly two "numbers" to be summed up; ...
I'd rather scan integral values (i.e. using %d and data type int) within a loop until one enters something that is not a valid number. This solves all of above mentioned issues:
int main() {
int sum=0;
int num=0;
printf("type in numbers to be summed up (type a non-number to exit):\n");
while (scanf("%d",&num)==1) {
sum += num;
}
printf("sum: %d\n",sum);
}
Intput/Output:
type in numbers to be summed up (type a non-number to exit):
10 20 30 x
sum: 60
There's a few things missing here.
For one thing, you're only reading one character with %c. You're storing it in &x, which, though confusing, is technically legal: since it's a sequence of 3 char-sized elements in memory, &x is a valid character address. However, x[1] and x[2] remain uninitialized; you're not setting them anywhere.
Secondly, you're not converting it to an integer value so it still has the value of the character '1' not decimal 1. '1' + '1' (note single quotes) will evaluate to 49 + 49 (note lack of quotes), 49 being the ascii equivalent to the character '1' - very different from the decimal value 1.
Finally, you're only summing the first and third character (the latter, being uninitialized, has an unknown value, certainly not one from your input). The second character is not a part of the final result.
If you want to read 3 integers, you should scan for ints, not characters, and you should scan for the number of them you wish to read. That would allow you to read numbers above 9 correctly.
But perhaps you do want to scan for one digit at a time; in which case, you'll certainly want to convert each digit character to it's integer equivalent. Since the digits 0 to 9 are contiguous and in ascending order in ascii, you can simiply subtract '0' from the character to get its decimal equivalent ( '1' - '0' == 1, '9'-'0'==9, etc.) But for this to work, you must ensure that you really have read a digit and not just any char. You might do so by verifying that its value was between '0' and '9', inclusive.
Regardless of whether you wish to sum integers or digits, you'll want to ensure you're reading each value you're going to sum before computing the final sum.
It might make more sense, given your use case, to keep scanning for ints in a loop until you run out of ints on the input stream. You don't really need to store them each; you can read one int at a time and add it to a running total.
Putting that all together, you might end up with something like this. Take these ideas and implement your running sum, and you'll have what you want for characters.
#include <stdio.h>
int main() {
char c; // we'll store our input here as we go
while( scanf(" %c", &c) == 1 ) { //one thing matched
if(c >= '0' && c <= '9'){ // it's a digit
printf("Read %c, decimal value of digit is %d\n", c, (int)(c-'0') );
}else {
printf("Invalid digit %c\n", c);
}
}
}
I run like this:
$ gcc -o t t.c && echo '1 2 3 4 5' | ./t
Read 1, decimal value of digit is 1
Read 2, decimal value of digit is 2
Read 3, decimal value of digit is 3
Read 4, decimal value of digit is 4
Read 5, decimal value of digit is 5
Change to scanf("%d") like described below to read multi-digit integers instead, changing the code accordingly.
#include <stdio.h>
int main() {
int c; // we'll store our input here as we go
while( scanf(" %d", &c) == 1 ) { //one thing matched
printf("Read %d; wasn't that easy?\n", c);
}
}
$ gcc -o t2 t2.c && echo '1 2 3 4 5' | ./t2
Read 1; wasn't that easy?
Read 2; wasn't that easy?
Read 3; wasn't that easy?
Read 4; wasn't that easy?
Read 5; wasn't that easy?
That approach can read any integer repesentation up to the min/max size of int, including multiple digits and even negative numbers:
$ gcc -o t2 t2.c && seq -1 -10 | ./t2
Read -1; wasn't that easy?
Read -2; wasn't that easy?
Read -3; wasn't that easy?
Read -4; wasn't that easy?
Read -5; wasn't that easy?
Read -6; wasn't that easy?
Read -7; wasn't that easy?
Read -8; wasn't that easy?
Read -9; wasn't that easy?
Read -10; wasn't that easy?
You could try:
int n1;
int n2;
scanf("%d %d", &n1, &n2);
int sum = n1 + n2;
printf("%d\n", sum);
If you want to add more than two numbers together, you could try:
printf("Enter how many numbers you want to add:\n");
int n;
scanf("%d", &n);
int sum;
for (int i = 0; i < n; i++) {
int in;
scanf("%d", &in);
sum += in;
}
printf("%d\n", sum);
Note:
At first the answer had C++ in the title and so I answered with C++ like this:
If you don't mind using cin and cout, you could try:
int n1;
int n2;
cin >> n1 >> n2;
cout << n1 + n2;
Running this program with n integers will return their sum by iterating from argv[1] to argv[n]. argv[0] is the name of the program.
Example:
./sum 1 3 returns 4
Code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i;
int sum;
if (argc > 1)
{
for (i = 1; i < argc; i++)
{
sum += (int)strtol(argv[i], NULL, 10);
}
printf("%d\n", sum);
}
else
{
fprintf(stderr,"Invalid number of arguments\n");
return(EXIT_FAILURE);
}
return(EXIT_SUCCESS);
}
You could use an array and a loop. This is a simple method.
#include<stdio.h>
#include<conio.h>
void main()
{
int sum=0, allocation[5],i,num;
printf("enter the number of elements");
scanf("%d",&num); // how many numbers are there??
printf("Enter the elements");
for(i=0;i<num;i++)
{
scanf("%d",&allocation[i]); //allocate the elements in the array say 3,4,5
sum=sum+allocation[i];
//0+3, sum=3
//3+4, sum=7
//7+5, sum=11
}
printf("Sum= %d",sum); //print Sum=11
getch();
}
#include <stdio.h>
int main () {
int num1,num2;
printf("Enter two numbers");
scanf("%d %d", &num1 &num2);
printf("Sum is = %d", num1+num2);
return 0;
}

Using switch statement in Fibonacci sequence

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.

Imputing fractions using arrays in C

My program asks the user for a numerator and then a denominator right after (If option 1 is chosen). I am pretty sure i got that part correct.I can not seem to figure out how to display the fraction(s) though when I hit option 2.
This is my code:
#include<stdio.h>
#include<string.h>
typedef struct fraction
{
int numerator, denom;
} fraction; //defined the fraction.
int main()
{//start of program
int z = 0;
int y = 0;
while (1)
{ //start of while loop
int choice;
printf("\nPress 1 to enter a fraction\n");
printf("Press 2 to view the entered fraction\n");
scanf("%d", &choice);
fraction arrFraction[100];
arrFraction[0].numerator = 0;
arrFraction[0].denom = 0;
if (choice == 1) // first option (enter numerator and then denom after)
{
printf("Enter the fraction\n");
scanf("%d", &arrFraction[y].numerator);
scanf("%d", &arrFraction[z].denom);
y++
z++;
}// end of first if statement(to enter the fraction)
if (choice == 2) //to view the entered fractions.
{
printf("\n-----------------------------");
for (int m = 0; m < z; m++)
{
printf(" %d / %d \n", arrFraction[y].numerator/arrFraction[z].denom);
}
printf("\n\n-----------------------------");
} // end of second if statement (to view the fraction entered earlier)
} // end of while loop
system("pause");
return(0);
}
You need to move fraction arrFraction[100]; out of while loop, otherwise, every iteration, there will be a new array.
That said,
printf(" %d / %d \n", arrFraction[y].numerator/arrFraction[z].denom);
is wrong, you're supplying two format specifiers but one argument. This invokes undefined behavior. Your compiler should have warned you.
I believe, what you want instead is
printf(" %d / %d \n", arrFraction[y].numerator, arrFraction[z].denom);
That said, I'm not very convinced with the overall logic. Why do you seem to need an array of 100 elements? If you're only interested in previous record (not records), use only a simple variable, not an array. Besides, you don;t need to have two separate index/ counters anyway. A single index will be able to manage the inputs in much concise and robust way.

adding an outer while loop to my c program - beginner 1 to continue 0 to stop

This is my first post on stack overflow, so this is my code so far, i'm just starting computer engineering and am having some trouble.
#include <stdio.h>
int main ( void ) {
int num, sum = 0, i, ssq = 0, isq, n;
printf("Enter an integer: ");
scanf("%d", &num);
for (i = 1; i <= num; i++) {
sum = sum + (i * i);
}
printf("The sum of the squares of integers from 0 to %d is %d\n", num, sum);
while (i >= 0) {
printf("Would you like to go again? (1 for yes, 0 for no): ");
scanf("%d", &i);
printf("Enter an integer: ");
scanf("%d", &num);
for (isq = 1; isq <= n; isq++);
ssq = ssq + (isq * isq);
printf("The sum of the squares of integers from 0 to %d is %d\n", num, sum);
if (i == 0) break;
}
return 0;
}
This is what I have so far believe it or not it took me 12 hours to do the first part, I've literally been up all night working on this, before the while loop and now I'm completely lost. I added the ssq=0, isq, and n ints in to try to help with no avail. At this point I'm just rearranging stuff for hours on end, this is my first post so please don't be too hard on me!
This contains a whole host of errors, from typos to code duplication, as #HappyCoder has noted above.
First of all, the outer part and the loop part do exactly the same. Think about it for a moment. You first do some task, unconditionally, then ask the user if they want to start over. The task itself doesn't change! Hence, what we can do is this:
do the task;
ask the user if they want to quit or go on;
if yes, return to the start.
In code, this can be done with an endless loop that you break out of if the user wants to stop:
while(1) {
// do user input and calculations here;
printf("Would you like to go again? (1 for yes, 0 for no): ");
scanf("%d", &i);
if (i == 0)
break;
}
See, now we only have one instance of the calculation code! Now, you can throw away half the variables declared in the beginning, since they are duplicate.
Now on to the calculations. You have an uninitialized variable, ssq, in the loop. See where code duplication can get you. In the outer part, it is initialized properly. Inside the loop, however, it is not guaranteed to hold any concrete value, most likely it contains garbage.
Also, as noted by #JohnHascall, this subtle error introduced most likely by a typo:
for (isq = 1; isq <= n; isq++); // <---- the evil semicolon
ssq = ssq + (isq * isq);
The semicolon after the for loop makes the loop empty, and the summation only happens once, but not in the loop, as you want it to be.
Then, you output (print) sum not ssq inside the loop, which is obviously not what you want to print. And, you use the uninitialized n variable from outside the loop as the boundary, instead of the user inputted num.
I want to add yet one more. Sanely naming the variables is a big deal as it helps you to catch potential errors and keep track of how variables are being used throughout the code, not to mention easier understanding of the code by others. Look: int i -> int choice better isn't it?
So we can rewrite the code like this:
#include <stdio.h>
int main ( void )
{
int boundary, choice, isq, ssq;
while (1) {
printf("Enter an integer: ");
scanf("%d", &boundary);
ssq = 0;
for (isq = 1; isq <= boundary; isq++) {
ssq = ssq + (isq * isq);
}
printf("The sum of the squares of integers from 0 to %d is %d\n", boundary, ssq);
printf("Would you like to go again? (1 for yes, 0 for no): ");
scanf("%d", &choice);
if (choice == 0)
break;
}
return 0;
}
for (isq=1; isq<=n; isq++);
ssq = ssq + (isq*isq);
The problem here is that 'n' is not initialized and not used in above scanf statement, you need to use 'num' instead of 'n'
for (isq=1; isq<=num; isq++)
ssq = ssq + (isq*isq);
One likely problem is here:
for (isq = 1; isq <= n; isq++);
ssq = ssq + (isq * isq);
You probably want:
for (isq = 1; isq <= n; isq++) {
ssq = ssq + (isq * isq);
}
Also, you should add:
ssq = 0;
above that loop (think about your 2nd trip through the loop).
Here is #iksemyonov 's answer refactored to honor the "no more than 7 lines in a method" rule (using a hard and fast arbitrary number like 7 is absurd, but the principle of making function do a specific understandable task is reasonable).
#include <stdio.h>
static int getBoundary ( void ) {
int boundary;
printf("Enter an integer: ");
scanf("%d", &boundary);
return boundary;
}
static int computeSSQ ( int limit ) {
int ssq = 0;
for (; limit > 0; --limit) ssq += (limit*limit);
return ssq;
}
static int again ( void ) {
int choice;
printf("Would you like to go again? (1 for yes, 0 for no): ");
scanf("%d", &choice);
return choice;
}
int main ( void ) {
do {
int boundary = getBoundary();
int ssq = computeSSQ(boundary);
printf("The sum of the squares of integers from 0 to %d is %d\n",
boundary, ssq);
} while (again());
return 0;
}
You have made a few mistakes here:
You have put a semicolon after the for loop inside the while block which should be removed.
Inside the while block you have accepted value for 'num' while you have used 'n' in the for loop (for which value is uninitialized). So you should accept the value of 'n' instead of 'num' or else replace 'n' in the for loop with 'num'.
If you want to exit the while loop immediately after user inputs 0 then move the if (i == 0) break; statement to below the scanf ("%d", &i) statement.
In the printf() statement next to the for loop, you have used value of 'sum' while you have calculated value for ssq.
Also you should write ssq = 0 after the printf() statement to reset its value to 0.
Correct all these and the program will work.
what you want to do was basically a menu driven program... i would suggest , like the above one's are right too... but another way you can do is using do{
//the task , i.e. the sum
} while(i!=0);
doing this since do while is an exit controlled loop as you might be knowing... so as in earlier stages u can be free from using break; keyword...
also as you are starting an early bird tip i would like to give is that the suggestion of using functions by #John above ....is good but not if you are doing mistakes in a normal int main() 15 lines code... since if you go in user defined functions like stated above you might go wrong in passing the arguments or basics of function passing... so go for a normal int main code for now...
Note i didnt meant that what # John said was wrong or something...just gave my view/advice

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