Addition program crashes when I give it input - c

I'm a C beginner, and this is by far my biggest program yet. It incorporates do while loops to restart the program, allow the user to add as many numbers as they want and ensure the correct letters are submitted for yes or no. Simple enough. Thing is, every number that I type adds up to 0.00, and the program gives me a segmentation fault (core dumped) error regardless of my choice for restart.
Errors:
I'm well aware that this could be some stupid detail I overlooked, but bear with me! Help is greatly appreciated.
Code:
/*Basic addition program*/
/*May 31 2018*/
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
char restart;
//Loop for restart
do{
/*
Starts Variables for Current number, sum,
number place count, and restart choice
*/
float currnum, sum;
int count = 1;
char restart = 'N';
//Loop for user input amount until 0 is submitted
do{
//Initiates number place ending array
char end[3];
printf("Basic Addition Program\nType 0 To Terminate\n\n");
//Chooses which ending to add to array
if(count == 1){
strcpy(end, "st");
}else if(count == 2){
strcpy(end, "nd");
}else if(count == 3){
strcpy(end, "rd");
}else if(count > 3){
strcpy(end, "th");
}
//Requests user input and adds to current number float
printf("Enter %d%s number: ", count, end);
scanf(" %d", &currnum);
//Clears Screen (Unix)
system("clear");
//Adds current number to overall sum
sum += currnum;
//Increases number count so that places shift by 1 (e.g 1st to 2nd)
count++;
}while(currnum != 0);
//States numbers inputted and sum
printf("You added %d numbers and got a sum of %.2f\n", count, sum);
//Do while loop for user error
do{
printf("Restart?(Y/N): ");
scanf(" %c", restart);
//Tests if numbers have ben inputted in lowercase and corrects accordingly
if(restart == 'y'){
restart = 'Y';
}else if(restart == 'n'){
restart = 'N';
}
}while(restart != 'Y' || restart != 'N' );
}while(restart == 'Y');
return 0;
}

One of the problematic statement is
scanf(" %c", restart); /* you need to provide the &(address) to store */
It should be
scanf(" %c", &restart);
you should read the compiler warning & solve yourself & compile with -Wall flag.
Also below statement
scanf("%d", &currnum); /* currnum is declared as float variable, use %f */
In the below code block
char restart;
do {
/* some code */
}while(restart == 'Y');
the restart is not initialized, your compiler could have warn you like
error: ‘restart’ is used uninitialized in this function
[-Werror=uninitialized]
So at the very first initialize restart like
char restart = 'Y';
and finally if you want to learn C properly, treat all warnings as error & then start solving problems. for e.g compile like below
gcc -Wall -pedantic -Wstrict-prototypes -Werror test.c

Related

taking the avg in C program

#include <stdio.h>
int main(int argc, char** argv)
{
int n;
int numbers;
int i=0;
int sum=0;
double average;
printf("\nPlease Enter the elements one by one\n");
while(i<n)
{
scanf("%d",&numbers);
sum = sum +numbers;
i++;
}
average = sum/n;
printf("\nSum of the %d Numbers = %d",n, sum);
printf("\nAverage of the %d Numbers = %.2f",n, average);
return 0;
}
i get the output "exited, floating point exception"
im not sure how to fix it.
i found online to add before the while loop
printf("\nPlease Enter How many Number you want?\n");
scanf("%d",&n);
but i dont want that there
Hint: you want the user to be able to signal to your application that they finished entering the elements. So you'd start with n=0 and then increment it each time the user provides a new element, and exit the loop when the user does "something" that you can detect.
For starters, let's say that the user closes the input by pressing Ctrl-Z on Windows, or Ctrl-D on Unix. The input will fail with EOF then - scanf() won't return 1 anymore. So you can check for this:
#include <stdio.h>
int main(int argc, char** argv)
{
int n = 0;
int sum = 0;
printf("\nPlease Enter the elements one by one. ");
#ifdef _WIN32
printf("Press Ctrl-Z to finish.\n");
#else
printf("Press Ctrl-D to finish.\n");
#endif
for (;;)
{
int number;
int result = scanf("%d", &number);
if (result == 1) break;
sum = sum + number;
n ++;
}
double average = (double)sum / n;
printf("\nSum of %d number(s) = %d\n",n, sum);
printf("Average of %d number(s) = %.2f\n",n, average);
return 0;
}
But this also ends the input when anything non-numeric is entered. Due to how scanf() is designed, you need to do something else to skip invalid input - usually by consuming input character-by-character until an end of line is reached. Thus, the variant that would not stop with invalid input, but allow the user another chance, needs to differentiate between scanf() returning EOF vs it returning 0 (invalid input):
#include <stdio.h>
void skip_input_till_next_line(void)
{
for (;;) {
char c;
if (scanf("%c", &c) != 1) break;
if (c == '\n') break;
}
}
int main(int argc, char** argv)
{
int n = 0;
int sum = 0;
printf("\nPlease Enter the elements one by one. ");
#ifdef _WIN32
printf("Press Ctrl-Z to finish.\n");
#else
printf("Press Ctrl-D to finish.\n");
#endif
for (;;)
{
int number;
int result = scanf(" %d", &number);
if (result == EOF) break;
if (result != 1) {
// We've got something that is not a number
fprintf(stderr, "Invalid input. Please try again.\n");
skip_input_till_next_line();
continue;
}
sum = sum + number;
n ++;
}
double average = (double)sum / n;
printf("\nSum of %d number(s) = %d\n",n, sum);
printf("Average of %d number(s) = %.2f\n",n, average);
return 0;
}
As a learner I'd recommend you to think about the pseudo code rather than the actual code.
Answers above are really good. I just want to add few things:
As a programmer you've to teach the hardware what you want it to do. Think:
Have you told your program how many numbers it takes as input? Is it limited or unlimited?
How will your program knows when to stop taking inputs?
I hope you agree that (sum n)/n would throw an error if user
doesn't enter anything or only enters 0?
What will happen if User enters characters instead?
Another important thing is that you need to clearly specify why you don't want to do certain thing in your code? This might help us understand better what are the limitations.
If you think about these things before and ask questions you'll learn better. Community is here to help you.

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);
}

Number guessing game in C

I had a problem at doing my number guessing game in C. While running the program it shows up return function when I put the char element in there. Can someone help me with this? Also how can I improve my code in order to make it workable? I'M really stuck with this issue.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
int main()
{
char s, n, q;
int b;
bool (1=true), (0=false);
int secret;
secret = rand();
int guess;
int seed;
srand(seed);
printf("Welcome to the guessing game!\n");
do{
printf("Menu: (s) to start a new game, (n) to set a new range, or (q) to quit:\n");
scanf("%s, %s, %s", s, n, q);
if((s==1))
{
printf("The secret number is Between 0 AND rand(). Guess\n");
scanf("%s", b);
}
else if((n ==1))
{
printf("Enter a new MAXIMUM\n");
scanf("%s", rand());
if(( s ==1))
{
printf("The secret number is Between 0 AND rand(). Guess\n");
scanf("%s", b);
printf("The secret number is between 0 and rand() Guess:");
scanf("%s", b);
if(guess = rand()){
printf("Congratulations you won, You took %d guesses!", b);
break;
}
else if(guess > rand())
{
printf("Too High, Guess again:");
}
else if(guess < rand()){
printf("Too Low, Guess Again:");
}
else{
printf("This number out of the number set!");
}
}
}
else{
printf("Unrecognized command");
}
}while(q == 1);
printf("You quited the game");
return 0;
}
This code has myriad issues to resolve. I'd suggest approaching your code writing process in small steps. It appears as though you wrote the entire program in one burst, ran it, and found it didn't work instead of incrementally adding small features and running each one to verify it works before moving on to the next step. Not doing this results in a difficult to debug program and a lack of understanding about how the program operates.
To be specific, try writing a three or four line program that collects and prints user input. Is the output working as you expect? Did you test its robustness on a variety of input? Can you write it to use a variety of data types? If something isn't working, did you research the problem and resolve it before steaming ahead?
Some areas of your program to investigate:
bool (1=true), (0=false); doesn't compile and isn't necessary for the program. If you #include <stdbool.h> you don't need to do this (you can simply write if (something == true)).
srand() is not properly called or seeded. Seed it once per program using the time() call from the header you included and call rand() once per game. Use the % operator to set the function output between 0 and max.
On each turn, compare guess against the value you previously stored rand() in rather than calling rand() during each comparison, which makes the game logic arbitrary.
%s input isn't appropriate; read chars %c and ints %d, passing appropriate variable references to scanf. scanf("%s, %s, %s", s, n, q); collects 3 whitespace separated strings for input instead of 1 char as the prompt suggests.
There is no game loop. Add an inner loop to run a game when the user chooses s and move your guess/response logic there.
Use more verbose variable names and correct brackets and indentation to improve readability.
Putting it all together, here's one possible working version. It could make better use of functions and implement secure user input (exercises for the reader):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
char menu_choice;
int guess;
int guesses;
int secret;
int max = 100;
srand(time(NULL));
printf("Welcome to the guessing game!\n");
for (;;) {
printf("\nMenu: (s) to start a new game, (n) to set a new range, or (q) to quit: ");
scanf(" %c", &menu_choice);
if (menu_choice == 's') {
guesses = 0;
secret = rand() % max;
for (;;) {
printf("\nThe secret number is between 0 and %d. Enter a guess: ", max);
scanf("%d", &guess);
guesses++;
if (guess == secret) {
printf("\nCongratulations, you won! You guessed %d in %d guesses!\n", secret, guesses);
break;
}
else if (guess > secret) {
printf("Too high! Guess again.");
}
else if (guess < secret) {
printf("Too low! Guess again.");
}
else if (guess >= max) {
puts("Out of range");
}
}
}
else if (menu_choice == 'n') {
printf("\nEnter a new maximum: ");
scanf("%d", &max);
}
else if (menu_choice == 'q') {
puts("\nGoodbye!");
break;
}
else {
puts("\nUnrecognized command.");
}
}
return 0;
}
Sample run:
Welcome to the guessing game!
Menu: (s) to start a new game, (n) to set a new range, or (q) to quit: n
Enter a new maximum: 50
Menu: (s) to start a new game, (n) to set a new range, or (q) to quit: s
The secret number is between 0 and 50. Enter a guess: 25
Too low! Guess again.
The secret number is between 0 and 50. Enter a guess: 37
Too low! Guess again.
The secret number is between 0 and 50. Enter a guess: 43
Too low! Guess again.
The secret number is between 0 and 50. Enter a guess: 47
Congratulations, you won! You guessed 47 in 4 guesses!
Menu: (s) to start a new game, (n) to set a new range, or (q) to quit: q
Goodbye!
printf("Menu: (s) to start a new game, (n) to set a new range, or (q) to quit:\n");
scanf("%s, %s, %s", s, n, q);
you dont need to use three variables s,n,q. you should ask the user to enter a single choice. either to start a new game or to quit or aything else.
secondly, rand() returns a random number every time. you are supposed to store random number somewhere. like this
rand_num=rand()
also
if(guess = rand())
is a wrong way of comparison. this should be
if(guess==rand_num)
finally binary search is the solution for your problem. please refer it on internet

How i cannot ignore 0(zero) as a grade?

int main(){
char students_number[30], students_grade[30];
char *number, *value;
int flag=0, students, i, grade, a=0, b=0, c=0, d=0, f=0;
float sum=0;
while(flag==0) // This while loop exist just because to run program until the number of students will be given correct..
{
printf("Please enter the number of students (It must be between 1-100): ");
scanf("%s",&students_number); // This scanf gets the number of students as an array instead of integer because the number which was given needs to be checked..
students = strtol(students_number, &number, 10); // strtol is a function of stdlib.h and checks the variable is whether int or not for this program..
if(students<=100 && students>0)
{
for(i=1;i<=students;i++)
{
printf("Please enter %d. student's grade (in integer form):",i);
scanf("%s",&students_grade);// This scanf gets the number of students as an array instead of integer because the number which was given needs to be checked..
grade = strtol(students_grade, &value, 10); // This line checks the grade which was given is integer or not by using strtol which is in the stdlib.h..
if(grade<0 || grade>100 || grade=='\0')
{
printf("The grade of the student was given incorrect!\n");
i--; // To make the for loop which is on the 25th line work again until the grade will be given correct..
}
else
{
if(grade<=50 && grade>=0) // This if and else if commands work for to count how many f,d,c,b and a are exist..
f++;
else if(grade<=60 && grade>=51)
d++;
else if(grade<=73 && grade>=61)
c++;
else if(grade<=85 && grade>=74)
b++;
else if(grade<=100 && grade>=86)
a++;
sum += grade;
}
}
sum /= students; // This command divides the sum of the grades to number of the students to get the average results in the class..
printf("\nThe average result of the class is %.2f..\n",sum);
printf("\nThe letter form of the all results are:\nNumber of F: %d\nNumber of D: %d\nNumber of C: %d\nNumber of B: %d\nNumber of A: %d\n",f,d,c,b,a);
flag = 1; // As it was mentioned before, this commands exist to break the while loop because the program was done successfully..
}
else // This if command controls the number of students wheter was given right or not..
{
printf("Please enter a proper number of students.\n");
flag = 0;
}
}
return 0;
}
Hello, this is my first question. I had to create a program which calculates the average of the results. But when i enter 0(zero) as a grade then it doesn't allow it just because i tried to exclude the every types except int type.
How can i make this correct?
You can use scanf to read a number and check that scanf done correctly its work:
from man scanf:
Return Value
These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.
So you can check that you've read an integer with scanf, without writing if (value == '\0'), which prevents you to read 0 grades...
for(i=1;i<=students;i++)
{
int ok;
printf("Please enter %d. student's grade (in integer form):",i);
/* read line from input. Why using fgets instead of scanf directly? See http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html*/
if (NULL == fgets(students_grade, sizeof students_grade, stdin))
{
perror("fgets");
exit(1);
}
/* **try** to parse what have been read */
ok = sscanf(students_grade, "%d", &value);
/* check that scanf has done its work */
if (1 != ok)
{
printf("The grade of the student was given incorrect!\n");
i--; // To make the for loop which is on the 25th line work again until the grade will be given correct..
}
else
{
if(grade<=50 && grade>=0) // This if and else if commands work for to count how many f,d,c,b and a are exist..
f++;
/* ... */
}
I also advice you to read this article: http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html.

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