Intro to C: Addition and Looping - c

I'm continuing on my quest to mastery C and I'm currently working on an exercise to have my rudimentary calculator continuously to prompt me for two operands and a operator. If the operator is not a '+', it displays an error message. Right now, I'm running into a few problems.
When I enter '+' it shows up two times. There is NOTHING I can find in my code that indicate that this would happen.
The first operand exhibits the same problem. I also do not know how to tell my code that I am done inputting.
Second operand is fine, but I still do not know how to terminate input.
Right after it shows the results, it loops back correctly but gives me an error message before prompting again.
http://tinypic.com/r/34ew5cx/6
NOTE: I know that you use lf to read double numbers in scanf, but for some reason lf isn't working for me and f is working just fine so disregard :)
Any observations are appreciated, along with any general suggestions on how to format code/ask questions on this site/how to approach problems like this. Thanks for your help!
int main () {
char mychar;
int a;
double op1;
double op2;
printf("Welcome to Andrew Hu's calculator program!\n"); //Greeting
while(1)
{ printf("Enter a mathematical operation to perform:\n");
scanf("%c", &mychar);
if(mychar == '+') //Valid Operators
a = 1;
else
a = 0;
if(a == 0) //Operator Checker, error if invalid
printf("\nError, not a valid operator\n");
else if(a == 1){
printf("%c\n", mychar),
printf("Enter OP1:\n"),
scanf("%f", &op1),
printf("%f\n", op1),
printf("Enter OP2:\n"),
scanf("%f\n", &op2),
printf("%f\n", op2),
printf("Result of %f %c %f = %f\n",
op1, mychar, op2, (op1 + op2) );
}
}

This is a typical case where your teacher/tutor/book/online tutorial/whatever suggests that using scanf() is a good idea, whereas it really isn't. You should also not make any assumptions about line endings, and as a very last and marginal sidenote, you should structure your code better (formatting and consistency regarding curly braces included).
What I suggest you do is leave poor scanf() alone, it doesn't always do what you think it does, this is especially the case when there are single characters, strings and newline characters to read. Instead, you'd be better off reading a line and parsing and/or validating it. It will also be much simpler if you do it correctly.
I also do not know how to tell my code that I am done inputting.
Well, you decide that. How about a quit operator? Example:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main()
{
char buf[0x100] = { 0 };
while (1) {
// If the user has entered "q", we enter the loop
fgets(buf, sizeof(buf), stdin);
if (buf[0] == 'q') break;
char *end;
float op1 = strtof(buf, &end); // parse 1st operand
while (isspace(*end)) {
end++;
}
char op = *end++; // get operator
float op2 = strtof(end, NULL); // parse 2nd operand
float r;
// do the calculation
switch (op) {
case '+':
r = op1 + op2;
break;
case '-':
r = op1 - op2;
break;
case '*':
r = op1 * op2;
break;
case '/':
r = op1 / op2;
break;
default:
fprintf(stderr, "Error: invalid operator '%c'\n", op);
continue;
break;
}
// print the result
printf("%f %c %f = %f\n", op1, op, op2, r);
}
return 0;
}

First thing, you need %lf in scanf to read a double, otherwise you just read a float and store it in half the double...
scanf("%lf", &op1),
This is not needed for printf because every float argument is first promoted to double...

Related

Arbitrary specific integer c program

So, recently I've asked question about arbitrary specific integer calculator program. It scans two string and is supposed to calculate it's sum and difference, multiplication, division and modulus. So far I think I'm really close to finishing the sum difference and multiplication functions. Here is how my code look like for addition function:
void sum(char* a, char* b)
{
//initializing values
int len1,len2,i;
int carry=0;
char *r;
// counting the digits
len1=strlen(a);
len2=strlen(b);
// checking which array is longer
if (len1>=len2)
{
// if first array is longer we allocate enough memory for the result
r=(char*)malloc((len1+1)*sizeof(char));
// starting from the LSB
for (i=0; i<=len2; ++i)
{ // mod 10 to extract only the last digit of the sum
// that becomes our new digit
*(r+len1-i)=(*(a+len1-i) + *(b+len2-i) + carry)%10;
carry=(*(a+len1-i)+*(b+len2-i))/10;
}
// copying the rest of the digits
for (i=len2+1; i<=len1; ++i)
*(r+len1-i)=*(a+len1-i);
}
//case when the other number has more digits
else
{
r=(char*)malloc((len2+1)*sizeof(char));
for (i=0; i<=len1; ++i)
{
*(r+len2-i)=(*(a+len1-i)+*(b+len2-i)+carry)%10;
carry=(*(a+len1-i)+*(b+len2-i))/10;
}
for (i=len1+1; i<=len2; ++i)
*(r+len2-i)=*(b+len2-i);
}
// printing the result
printf("The result is: \n %s \n", r);
}
The problem is when I try to call for the function in main the end result just gives errors, even though there are not any errors while compiling the code. It might be a problem in main so here is how my main looks like.
int main()
{
FILE *fp;
char *fi=NULL, *se=NULL;
char o;
int i=0;
fp= fopen("/CalculatorHistory.txt", "r+");
opening();
fi=(char*)malloc(60*sizeof(char));
se=(char*)malloc(60*sizeof(char));
while(i<2)
{
first();
scanf("%s", fi);
// I am not sure when im saving pointer arrays, if it works like this
// or i should save it in a for loop
fprintf(fp, fi);
oper();
scanf(" %c", &o);
fprintf(fp, o);
second();
scanf("%s", se);
fprintf(fp, se);
switch (o)
{
case '+':
sum(fi, se);
case '-':
sub(fi, se);
case '*':
mul(fi, se);
case '/':
div(fi, se);
case '%':
mod(fi, se);
}
}
return 0;
}
I hope that somebody can help me. I'm pretty lost and still really new to c programming.

Why won't my result update after the first iteration(?)

#include <stdio.h>
#include <math.h>
void scan_data(char *op, float *operand);
float do_next_op(char op, float operand, float *accumulator);
int main(void)
{
char op;
float operand;
float accumulator = 0;
do
{
printf(" + add\n - subtract\n * multiply\n / divide\n ^ power\n q quit\n\n");
scan_data(&op, &operand);
if(op == 'q' || op == 'Q')
{
printf("Final result is %.1f\n", do_next_op(op, operand, &accumulator));
break;
}
else
{
printf("result so far is %.1f\n", do_next_op(op, operand, &accumulator));
}
}while(op != 'q' || op == 'Q');
}
void scan_data(char *op, float *operand)
{
scanf("%c%f",op, operand);
}
float do_next_op(char op, float operand, float *accumulator)
{
switch(op)
{
case('+'):
*accumulator = *accumulator + operand;
break;
case('-'):
*accumulator = *accumulator - operand;
break;
case('*'):
*accumulator = *accumulator * operand;
break;
case('/'):
*accumulator = *accumulator / operand;
break;
case('^'):
*accumulator = pow(*accumulator,operand);
break;
}
return *accumulator;
}
I'm trying to code a "simple" calculator where if i type
+5.0
result so far is 5.0
^2
result so far is 25.0
/ 2.0
result so far is 12.5
Q 0
final result is 12.5
The problem is, the code will "correctly" output the first operation but if i put anymore operation after that I doesn't update to the new value.
How can I fix the code to do what I intend to do?
I'm sorry in advance if my question wording and format is off, I don't know how to ask it in a proper way.
the problem is in the statement:
scanf("%c%f",op, operand);
After the first iteration, there is a left over newline in stdin
That newline is a 'white space', typically \n
That 'white space must be consumed before the %c rather than the %c consuming it. Suggest:
scanf(" %c%f",op, operand);
where the leading space in the format string consumes that 'white space'
regarding the statement:
*accumulator = pow(*accumulator,operand);
the pow() function expects to be working with double values, not float values. Suggest:
*accumulator = powf(*accumulator,operand);
Notice this is calling powf() not pow()

Scanning Values Until Getting a Significant Character in C

For my homework, I am trying to code a calculator which can also calculate average of taken numbers. I don't want to ask for number of numbers because our teacher don't want it in that way. So I thought of scanning values until the user presses "p". But as you would guess, the numbers are float and "p" is a character. What I want to do is assigning the value scanned to both of them if it is possible. I tried different ways, played with the codes but it isn't working properly. So I am seeking your advice.
It prints a value when p is inputted as like 3rd, 5th, 7th (oddth) number (sometimes right, sometimes wrong but I can fix it if I figure this out). But it doesn't print a value in other occasions and expects infinite inputs from the user.
This is the code I have written for this. scanf("%f %c", &number1, &pause); command is where I want to know about, actually.
#include<stdio.h>
float number1, number2, i, result;
char pause;
int main() {
scanf("%f", &number1);
i = 0;
while (pause != 'p') {
number2 = number1 + number2;
scanf("%f %c", &number1, &pause);
i++;
}
result = number2 / (i - 1);
printf("%f", result);
}
Use double not floats if there is no specific reason to do so (like using uC without double FPU).
You do not initialize the variables
Always check the result of the I/O operation.
#include <stdio.h>
int main ()
{
double number1= 0, number2 = 0, i = 0, result = 0;
char pause = 0;
char line[128];
while (pause != 'p')
{
if(fgets(line, sizeof(line), stdin))
{
if(sscanf(line, "%lf %c",&number1, &pause) != 2)
{
printf("Wrong input - try again\n");
pause = 0;
continue;
}
number2 = number1 + number2;
i++;
}
else
{
// do something with I/O error
}
}
result = number2 / (i-1);
printf("%lf",result);
}
You can play with it yourself : https://onlinegdb.com/Hy3y94-3r
I noticed 3 problems with your code.
First I would advise you to use meaningful variables names. number1, number2, etc. and the i which represents the number of inputs given can be an int instead of a float.
Secondly, you lack of printing to the user what's going on in your program; it's better to have messages like "enter your number, do you wanna stop? the result is...etc".
Lastly, having two inputs in one line of code can make it hard to debug, knowing that reading strings and characters in C is already hard for beginners. For example, %c does not skip whitespace before converting a character and can get newline character from the previous data entry.
Here is my fix: I changed some variables' names, printed some messages and read the two inputs in two different lines with adding scanf(" %c") with the space to avoid that problem.
#include<stdio.h>
float sum, temp, result;
int nb;
char pause;
int main () {
pause='a';
while (pause != 'p'){
printf("Enter your number: ");
scanf("%f",&temp);
sum+=temp;
nb++;
printf("type 'p' if you want to stop: ");
scanf(" %c",&pause);
}
result = sum / nb;
printf("the average is : %f",result);
}
I tested it, should work fine
Edit: after explaining that you don't want to ask the user each time, here is how the code should work (the case that the user don't input a float is not treated, and just take it as zero
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
float sum, temp, result;
int nb;
char input[50];
int main () {
sum=0;
nb=0;
printf("Enter your numbers, then type 'p' to stop\n");
do{
printf("Enter your next number: ");
scanf("%s", input);
if(strcmp(input,"p")!=0)
{
float temp= atof(input);
sum+=temp;
nb++;
}
}while(strcmp(input,"p")!=0);
if(nb!=0)
result = sum / nb;
printf("\nThe average is : %f",result);
}

Calculator program requires + and - to be entered twice

I am writing a simple calculator program to add, subtract, multiply, divide and do exponential equations. The program must repeat until "q0" is entered and it must have two functions called by the main function like I have written. The problem is when I run the program the first number shows up fine and then I can multiply, divide, and do exponential functions fine but if I want to add or subtract I must enter the + or - twice for it to count it. This is the program I have written:
#include <stdio.h>
#include <math.h>
void scan_data(char *oprter, double *oprand);
void do_next_op(char oprter, double oprand, double *accum);
int
main(void)
{
double nmber, /* input/output - operand */
total; /* output - final result */
char sign; /* input/output - operator */
total = 0;
do {
scan_data(&sign, &nmber);
do_next_op(sign, nmber, &total);
} while (sign != 'q');
printf("Final result is %.2f", total);
return (0);
}
/*
* Gathers operator and operand to perform calculation
* Post: results are stored in cells pointed to by oprter, and oprand
*/
void
scan_data(char *oprter, /* input - amount being withdrawn */
double *oprand) /* output - number of tens */
{
double amount;
amount = 0;
scanf("%c", &*oprter);
scanf("%lf", &amount);
*oprand = amount;
}
/*
* Performs calculation and displays results
* Pre: oprter and oprand are defined
* Post: function results are stored in cell pointed to by accum
*/
void
do_next_op(char oprter,
double oprand,
double *accum)
{
double tot_amount;
tot_amount = *accum;
switch(oprter)
{
case '+':
tot_amount = (tot_amount + oprand);
printf("result so far is %.2f\n", tot_amount);
break;
case '-':
tot_amount = (tot_amount - oprand);
printf("result so far is %.2f\n", tot_amount);
break;
case '*':
tot_amount = tot_amount * oprand;
printf("result so far is %.2f\n", tot_amount);
break;
case '/':
tot_amount = tot_amount / oprand;
printf("result so far is %.2f\n", tot_amount);
break;
case '^':
tot_amount = pow(tot_amount, oprand);
printf("result so far is %.2f\n", tot_amount);
break;
}
*accum = tot_amount;
}
An example of what it is doing follows:
+5
result so far is 5.00
+5
-5
++5
result so far is 10.00
--5
result so far is 5.00
*2
result so far is 10.00
/2
result so far is 5.00
^2
result so far is 25.00
q0
Final result is 25.00
The problem is most likely that scanf leaves the newline in the input buffer when you do
scanf("%lf", &amount);
That means that the next call to
scanf("%c", oprter);
it will read that newline.
This can be solved by asking scanf to read and skip all leading whitespace by adding a single space to the scanf format string like
scanf(" %c", oprter);
// ^
// |
// Note space here

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