How to solve input duplicate problem In C [duplicate] - c

This question already has answers here:
What is the effect of trailing white space in a scanf() format string?
(4 answers)
problems with scanf("%d\n",&i) [duplicate]
(3 answers)
Closed 3 years ago.
when i input base value, it will not be recognized first in c
#include <stdio.h>
main(void)
{
float base, height, area;
printf("area of triangle=?\n");
printf("base=");
scanf("%f\n", &base);
printf("height=");
scanf("%f\n", &height);
area = base*height / 2;
printf("area = %f\n", area);
return 0;
}

You have 2 primary problems in your code.
(1) Do not include '\n' in your format specifier. Format specifiers such as "%f" skip whitespace by default. So use (subject to #2):
scanf("%f", &base)
(2) Validate EVERY user input by checking the return of the input function used. What happens if the user reached for the '4' key by hit 'R' my mistake? What happens then? (if it is the 1st digit -- undefined behavior as you blindly assume the input succeeded). Instead, validate the return, e.g.
if (scanf("%f", &base) != 1) {
fputs ("error: invalid float - base.\n", stderr);
return 1;
}
Putting it altogether, you could do:
#include <stdio.h>
int main (void)
{
float base, height, area;
fputs ("area of triangle=?\nbase=", stdout);
if (scanf("%f", &base) != 1) {
fputs ("error: invalid float - base.\n", stderr);
return 1;
}
fputs ("height=", stdout);
if (scanf("%f", &height) != 1) {
fputs ("error: invalid float - height.\n", stderr);
return 1;
}
area = base * height / 2.;
printf ("\narea = %f\n", area);
return 0;
}
(note: nit - there is no need to use the variadic printf function if there are no conversions involved, simply use fputs (or just puts if you want a default '\n' at the end). A good compiler will optimize this for your, but showing an understanding of what the proper tool for the job is has merit)
Example Use/Output
$ ./bin/trianglearea
area of triangle=?
base=3
height=4
area = 6.000000
Look things over and let me know if you have further questions.

Scanf using only format
scanf("%f",&base);

printf("base=");
scanf("%f", &base);
printf("\n");
printf("height=");
scanf("%f", &height);
printf("\n");

Related

Loop Gone wrong [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 2 years ago.
I'm pretty new in C.
My problem is the code keep looping at that line ( you can check the code) while what i wanted is for it to loop the whole for statement, not a single line.
English is not my first language so i'm truly sorry
#include <stdio.h>
int hw;
int uts;
int uas;
float hasil_uts;
float hasil_uas;
float hasil_hw;
char opsi;
int main (void) {
int n1; //Homework
int c1;
for (c1=0;opsi != 'n';c1++) {
printf ("Input : ");
scanf ("%d",&hw);
n1 += 1;
hasil_hw += hw;
printf ("\nInput another marks? (y/n)"); // it loops here when it run
scanf ("%c",&opsi);
}
return 0;
}
you have to add one space in scanf like this scanf (" %c",&opsi); ,otherwise you will take \n as your character in scanf.
also note that you are using uninitialized variable n1 and hasil_hw. you have to add n1=0 and hasil_hw=0 to your code.
also as mentioned in comments you should check scanf returned value.
look
int hw;
int uts;
int uas;
float hasil_uts;
float hasil_uas;
float hasil_hw=0;
char opsi;
int main(void) {
int n1=0; //Homework
int c1;
for (c1 = 0; opsi != 'n'; c1++) {
printf("Input : ");
if ( scanf("%d", &hw) != 1)
{
fputs ("error: invalid value.\n", stderr);
return 1;
}
n1 += 1;
hasil_hw += hw;
printf("\nInput another marks? (y/n)"); // it loops here when it run
if (scanf(" %c", &opsi) != 1)//add space before %c
{
fputs ("error: invalid value.\n", stderr);
return 1;
}
}
return 0;
}

Using switch statements to call functions

I'm trying to write a program in C that uses switch statements to decide which called function to use to convert various values. My instructions were as follows:
"Create a program to convert Fahrenheit to Celsius, Celsius to Fahrenheit, inches to centimeter, and centimeters to inches. Put your choices into a switch statement so they will appear on the screen like below:
Select from the menu below to covert temperature or linear menus:
1 Convert Fahrenheit to Celsius
2 Convert Celsius to Fahrenheit
3 Convert Inches to Centimes
4 Convert Centimeters to Inches
5 Exit the program
Enter your selection:
ake each of the conversion routines a function that you will call from the main program. Each of the selections should be a case in a switch statement. Be sure to comment all your code according to the coding standards.
When I run the program and enter the choice followed by the value to convert, a weird number shows up followed by
ProgramExiting.ProgramExiting.
Here is my code:
#include <stdio.h>
void FahrenheitToCelsiusConversion (double conversionValue) {
double output;
output = conversionValue / (9.0 / 5.0) - 32;
printf("%d", output);
}
void CelsiusToFahrenheitConversion (double conversionValue) {
double output;
output = conversionValue * (9.0 / 5.0) + 32;
printf("%d", output);
}
void InchesToCentimetersConversion (double conversionValue) {
double output;
output = conversionValue * 2.54;
printf("%d", output);
}
void CentimetersToInchesConversion (double conversionValue) {
double output;
output = conversionValue / 2.54;
printf("%d", output);
}
int main(void) {
int conversionChoice;
double conversionValue;
printf("Select from the menu below to convert temperature or linear\n");
printf("menus:");
printf("\n");
printf("1 Convert Fahrenheit to Celsius\n");
printf("2 Convert Celsius to Fahrenheit\n");
printf("3 Convert Inches to Centimeters\n");
printf("4 Convert Centimeters to Inches\n");
printf("5 Exit the Program\n");
scanf("%d", &conversionChoice);
printf("Enter the value you wish to convert:\n");
scanf("%d", &conversionValue);
switch (conversionChoice) {
case 1:
FahrenheitToCelsiusConversion(conversionValue);
case 2:
CelsiusToFahrenheitConversion(conversionValue);
case 3:
InchesToCentimetersConversion(conversionValue);
case 4:
CentimetersToInchesConversion(conversionValue);
case 5:
printf("Program exiting.");
default:
printf("Program exiting.");
}
return 0;
}
You are missing breaks for a start. (so if you pick option 1 it will also perform options 2 3 4 and 5)
conversionValue is a double but you scan it in with %d. This means you aren't converting the value you think you are. Basic debug (printing your input values) would highlight that.
All your prints are trying to print a double with %d (should be %lf for doubles)
Combining output with calculations is bad. i.e. Your convert routines should return the converted value and the print should be outside the convert function.
As a follow on to your comments, understand that printf will print doubles using "%f" by default, however, to read a double with scanf you must use the l length-modifier, e.g. "%lf". A mismatch in format specifiers results in Undefined Behavior.
Further, as you found, your F->C conversion logic needs... help. The 32 is being subtracted at the wrong point, it should be:
void FahrenheitToCelsiusConversion (double conversionValue) {
double output;
output = (conversionValue - 32) / (9.0 / 5.0);
printf ("%.2f\n", output);
}
(note: the printf format change as well)
Further, in main() you need only a single call to printf (or fputs since no conversions are involved) to print the entire menu. When you terminate a line with a double-quote and the next begins with a double-quote, C will concatenate the strings, e.g.
printf ("\nSelect from the menu below to convert temperature or linear\n"
"menus:\n\n"
" 1 Convert Fahrenheit to Celsius\n"
" 2 Convert Celsius to Fahrenheit\n"
" 3 Convert Inches to Centimeters\n"
" 4 Convert Centimeters to Inches\n"
" 5 Exit the Program\n\n"
"choice: ");
Always, always validate all User Input, this means at minimum validating the return of scanf (and if not exiting after a matching failure -- you must read and discard all offending characters that remain in stdin because when a matching failure occurs, no further characters are removed from the input buffer and any offending characters that caused the matching failure remain unread just waiting to bite you again on your next attempt to read from the input buffer).
At minimum check that the number of conversions expected completed successfully (and you should further check that any numeric input is within range, if applicable), e.g.
if (scanf ("%d", &conversionChoice) != 1 || conversionChoice < 1 ||
conversionChoice > 5) {
fputs ("error: invalid input, or value out of range.\n", stderr);
return 1;
}
printf ("\nEnter the value you wish to convert: ");
if (scanf ("%lf", &conversionValue) != 1) {
fputs ("error: invalid value input.\n", stderr);
return 1;
}
You indicate you have added break statements to your switch statement, but after our discussion of the default fall-through behavior, do you understand why the following works?
switch (conversionChoice) {
case 1:
FahrenheitToCelsiusConversion(conversionValue);
break;
case 2:
CelsiusToFahrenheitConversion(conversionValue);
break;
case 3:
InchesToCentimetersConversion(conversionValue);
break;
case 4:
CentimetersToInchesConversion(conversionValue);
break;
case 5: /* here you CAN use fall-through */
default:
printf("Program exiting.");
break;
}
Putting all the pieces together, you can do something like the following:
#include <stdio.h>
void FahrenheitToCelsiusConversion (double conversionValue) {
double output;
output = (conversionValue - 32) / (9.0 / 5.0);
printf ("%.2f\n", output);
}
void CelsiusToFahrenheitConversion (double conversionValue) {
double output;
output = conversionValue * (9.0 / 5.0) + 32;
printf ("%.2f\n", output);
}
void InchesToCentimetersConversion (double conversionValue) {
double output;
output = conversionValue * 2.54;
printf ("%.2f\n", output);
}
void CentimetersToInchesConversion (double conversionValue) {
double output;
output = conversionValue / 2.54;
printf ("%.2f\n", output);
}
int main (void) {
int conversionChoice;
double conversionValue;
printf ("\nSelect from the menu below to convert temperature or linear\n"
"menus:\n\n"
" 1 Convert Fahrenheit to Celsius\n"
" 2 Convert Celsius to Fahrenheit\n"
" 3 Convert Inches to Centimeters\n"
" 4 Convert Centimeters to Inches\n"
" 5 Exit the Program\n\n"
"choice: ");
if (scanf ("%d", &conversionChoice) != 1 || conversionChoice < 1 ||
conversionChoice > 5) {
fputs ("error: invalid input, or value out of range.\n", stderr);
return 1;
}
printf ("\nEnter the value you wish to convert: ");
if (scanf ("%lf", &conversionValue) != 1) {
fputs ("error: invalid value input.\n", stderr);
return 1;
}
switch (conversionChoice) {
case 1:
FahrenheitToCelsiusConversion(conversionValue);
break;
case 2:
CelsiusToFahrenheitConversion(conversionValue);
break;
case 3:
InchesToCentimetersConversion(conversionValue);
break;
case 4:
CentimetersToInchesConversion(conversionValue);
break;
case 5: /* here you CAN use fall-through */
default:
printf("Program exiting.");
break;
}
return 0;
}
Example Use/Output
$ ./bin/tempconv
Select from the menu below to convert temperature or linear
menus:
1 Convert Fahrenheit to Celsius
2 Convert Celsius to Fahrenheit
3 Convert Inches to Centimeters
4 Convert Centimeters to Inches
5 Exit the Program
choice: 1
Enter the value you wish to convert: 212
100.00
Always compile with warnings enabled, and do not accept code until it compiles cleanly without warning. To enable warnings add -Wall -Wextra to your gcc or clang compile string. (add -pedantic for several additional warnings). For clang, instead you can use -Weverything. For VS (cl.exe on windoze), add /W3 (or use /Wall but you will get quite a few extraneous non-code related warnings). Read and understand each warning. They will identify any problems, and the exact line on which they occur. You can learn a lot by listening to what your compiler is telling you.
While not an error, C generally avoids the use of camelCase or MixedCase variable names in favor of all lower-case while reserving upper-case names for use with macros and constants. It is a matter of style -- so it is completely up to you, but failing to follow it can lead to the wrong first impression in some circles. See e.g. NASA - C Style Guide, 1994 As with anything outside the C-Standard, you are bound to find contra-indications, but generally camelCase or MixedCase are left to java or C++.
If you have any further questions, please just let me know.

Calculate GPA of a student without arrays [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
whats wrong in my code? it doesn't give the values properly and when i insert q it doesn't execute properly....
#include<stdio.h>
void main()
{
double a=0, x, ctot;
double y, stot;
char b, c='q';
double score=x*y;
while(a<200){
printf("Enter no of Credits of the subject = ");
scanf("%lf\n",&x);
printf("Enter the score for the subject = ");
scanf("%lf\n",&y);
scanf("%c\n",&b);
if(b=='q'){
break;
}else{
ctot+=x;
stot+=score;
a++;
}
}
printf("GPA of the student = %f\n", stot/ctot);
}
An attempt to access a variable with indeterminate value (meaning uninitialized) invokes Undefined Behavior and the valid operation of your code ceases at that point. It can appear to work properly or SegFault or anything in between.
To avoid uninitialized values, always initialize them -- especially when you are just beginning to program. (it will save you from yourself...), e.g.
int a = 0; /* always initialize all variables - good practice */
double ctot = 0.0,
stot = 0.0,
score = 0.0,
x = 0.0,
y = 0.0;
char c = 0;
The proper declarations for main are int main (void) and int main (int argc, char **argv) (which you will see written with the equivalent char *argv[]). note: main is a function of type int and it returns a value. See: C11 Standard ยง5.1.2.2.1 Program startup p1 (draft n1570). See also: See What should main() return in C and C++?
While there are some ancient compilers, and some micro-controllers that allow void main(), it is a non-standard invocation, and any worthwhile compiler will warn. (you are compiling with compiler-warning enabled right?, e.g. -Wall -Wextra for gcc/clang or /W3 for VS (cl.exe))
You must check the return of scanf every time and validate the return is equal to the number of conversions you have requested -- otherwise a matching or input failure has occurred (or the user canceled by generating a manual EOF). This is the only way you can insure you are processing valid data and not further invoking Undefined Behavior (or throwing yourself into an endless input loop). You must always empty stdin after each input. Your '\n' gimick in the format string will not work. A simple way to empty stdin is to define a helper-function to call after each input to remove any extraneous or additional characters that remain unread, e.g.
/* simple function to empty remaining chars in stdin */
void empty_stdin (void) /* if no parameter - spcecify 'void' explicitly */
{
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
...
printf ("Enter no of Credits of the subject = ");
if (scanf ("%lf", &x) != 1) { /* validate EVERY input */
fprintf (stderr, "error: invalid input for 'x'.\n");
return 1;
}
empty_stdin(); /* empty stdin, your \n gimick doesn't work */
Putting it altogether, you could do something similar to the following:
#include <stdio.h>
/* simple function to empty remaining chars in stdin */
void empty_stdin (void) /* if no parameter - spcecify 'void' explicitly */
{
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
int main (void) {
int a = 0; /* always initialize all variables - good practice */
double ctot = 0.0,
stot = 0.0,
score = 0.0,
x = 0.0,
y = 0.0;
char c = 0;
for (; a < 200; a++) { /* loop however you like */
printf ("Enter no of Credits of the subject = ");
if (scanf ("%lf", &x) != 1) { /* validate EVERY input */
fprintf (stderr, "error: invalid input for 'x'.\n");
return 1;
}
empty_stdin(); /* empty stdin, your \n gimick doesn't work */
printf ("Enter the score for the subject = ");
if (scanf ("%lf", &y) != 1) {
fprintf (stderr, "error: invalid input for 'y'.\n");
return 1;
}
empty_stdin();
score = x * y; /* compute values each iteration */
ctot += x;
stot += score;
/* prompt for additional credits? */
printf ("add additional credits? (y/n): ");
if (scanf (" %c", &c) != 1) {
fprintf (stderr, "error: user canceled input.\n");
return 1;
}
empty_stdin();
if (c == 'n' || c == 'N') /* you can use 'q', but (y/n) is fine */
break;
}
printf ("\nGPA of the student = %f\n", stot/ctot);
return 0;
}
(can you figure out why if (scanf (" %c", &c) != 1) can only mean that the user canceled input?)
Example Use/Output
note: there are extraneous characters intentionally input below to provide example of how the simple additions to your code handle them safely. (try the input below with your original code and see what happens)
$ ./bin/credits_grades
Enter no of Credits of the subject = 3
Enter the score for the subject = 90
add additional credits? (y/n): y
Enter no of Credits of the subject = 4 (seemed like 40)
Enter the score for the subject = 80 (thank god!)
add additional credits? (y/n): y
Enter no of Credits of the subject = 3
Enter the score for the subject = 85
add additional credits? (y/n): n
GPA of the student = 84.500000
Look things over and let me know if you have further questions.
Initializing ctot and stot and re-positioning score=x*y your code will work . Try this edited code this works fine :-
#include <stdio.h>
void main()
{
double a = 0, x, ctot;
double y, stot;
char b, c = 'q';
double score;
ctot = 0; // initialize ctot and stot #ERROR1
stot = 0;
while (a < 200)
{
printf("\n Enter no of Credits of the subject = ");
scanf("%lf", &x);
printf("\n Enter the score for the subject = ");
scanf("%lf", &y);
getchar(); // to manage the addtional \n from scanf()
score = x * y; // computing score #ERROR2
scanf("%c", &b);
if (b == 'q')
{
break;
}
else
{
ctot += x;
stot += score;
a++;
}
}
printf("\n GPA of the student = %f", stot / ctot);
}
based on comments of #mch and #David C. Rankin
should modify the slot+=score to slot+=x*y
#include<stdio.h>
void main()
{
double a=0, x, ctot;
double y, stot;
char b, c='q';
double score=x*y;
while(a<200){
printf("Enter no of Credits of the subject = ");
scanf("%lf\n",&x);
printf("Enter the score for the subject = ");
scanf("%lf\n",&y);
scanf("%c\n",&b);
if(b=='q'){
break;
}else{
ctot+=x;
stot+=x*y;
a++;
}
}
printf("GPA of the student = %f\n", stot/ctot);
}

C language : why when input a float number in an int declared variable the result varries

using a simple code:
#include <stdio.h>
int main(int argc, int **argv)
{
int A, B, C, D, E, F;
printf ("input 1 : ");
scanf ("%d", &A);
printf ("input 2 : ");
scanf ("%d", &B);
C = A + B;
D = A - B;
E = A * B;
F = A / B;
printf ("sum : %d\n", C);
printf ("difference : %d\n", D);
printf ("product : %d\n", E);
printf ("quotient : %d\n", F);
return 0;
}
My question is as such, in the first scanf [p.s I know I can use other input methods its for a project] if you input a float/double number such as 1.3 or 20.5
the sum and difference are quite random for me,anyone can explain to me why the results are what they are?
Continuing from the comments, you must always validate all input (especially user input). All input functions provide a return. The scanf family returns the match count, the number of successful conversions processed based on the number of format specifiers in the format string. You use that to validate your input. E.g., at minimum:
#include <stdio.h>
int main(int argc, int **argv)
{
int A, B, C, D, E, F;
printf ("input 1 : ");
if (scanf ("%d", &A) != 1) {
fprintf (stderr, "error: invalid input - A.\n");
return 1;
}
printf ("input 2 : ");
if (scanf ("%d", &B) != 1 || B == 0) {
fprintf (stderr, "error: invalid input - B.\n");
return 1;
}
C = A + B;
D = A - B;
E = A * B;
F = A / B;
printf ("sum : %d\n", C);
printf ("difference : %d\n", D);
printf ("product : %d\n", E);
printf ("quotient : %d\n", F);
return 0;
}
note: your "quotient" will always be the result of integer division and truncated accordingly.
The first scanf(), if the input has a decimal point will stop at the decimal point and leave it to be read on the next operation. For input of 1.3, this means A will get the value 1, and the .3 will remain in the input stream to be read. This is because of the %d format - which tells scanf() to expect an integral value, and to stop on any characters that do appear in any representation of an integral value. A decimal point is one such character that is not used in the representation of an integral value.
The next operation (scanf("%d", &B)) immediately encounters the decimal point and returns, without changing B.
Since B is not initialised at all (before, during, or after the scanf("%d", &B)) in the program, any subsequent attempt to access its value gives undefined behaviour. Among other things, this can mean the value of B is indeterminate. From what you describe, for your setup, that results in "random" input.
If you're expecting to read input that looks like floating point values (e.g. that contains a decimal point) either read as floating point (e.g. %f format, and variables of a floating point type) or read a whole line (e.g. using fgets()) and check the contents of the line BEFORE trying to read integral values from it.
If you insist on using scanf(), check its return value. On the second call of scanf() in your scenario, scanf() will return 0 rather than 1 (since it has read no values, rather than the one value the format string specified). Which is an indication that something has gone wrong reading the input.

Please explain to me why this simple C program with if statements doesn't work?

I've just learned about if statements and tried to make some sort of calculator, but it won't work. It asks you to enter an operation (for now only addition works), and then it asks for two integers. It's super simple, but it won't work. The error may be obvious to you guys, but I just don't see it. Please help! Here's the code:
int main()
{
int operation;
int addition;
float firstNumber;
float secondNumber;
printf("Type in an operation.\n");
scanf(" %s", operation);
if(operation = addition){
printf("Please, enter an integer.\n");
scanf(" %f", &firstNumber);
printf("Please, enter a second integer.\n");
scanf(" %f", &secondNumber);
printf("Answer: %d", firstNumber + secondNumber);
}else{
printf("Sorry, only addition works..");
}
return 0;
}
Why should your code work?
int operation;
/* int for storing a string? huh?
* or were you thinking about function pointers ?
* Normally you would use a char[]
*/
scanf(" %s", operation);
/* Using %s specifier looks weird .
* Also scanf is reading into operation and not &operation
* So is having a space in the in the beginning of the format string.
*/
int addition;
/* Automatic variables are not initialized as per the standard
* But what about the type?
* Were you intending to do something like char addition[]="addition"
*/
if(operation = addition)
/* If you somehow manage to get to this point
* you have another problem you do an assignment in the statement using =
* You should have been using ==
*/
wrong:
if(operation = addition)
{
};
correct:
if(operation == addition)
{
};

Resources