I'm trying to create a program that asks the user what conversion the user wants to do, then scans for the number they want to convert, then does the conversion and spits it out.
Here are the instructions that include desired outputs:
Building on assignment one, create a program to with the choice of convert Celsius to Fahrenheit or Fahrenheit to Celsius using “ifelse” statement to chose which conversion you want to use. Be sure to include the correct header in your .C file. Use the K and R formatting. Name your file “first Initial last name-assingment2.c” ex: “rgalus-assingment2.c” Below is what I expect the program output to look like:
Enter 1 to convert Celsius to Fahrenheit
Enter 2 to convert Fahrenheit to Celsius
Enter 0 to exit
1
10
10 degrees Celsius is equal to 50 degrees Fahrenheit
Enter 1 to convert Celsius to Fahrenheit
Enter 2 to convert Fahrenheit to Celsius
Enter 0 to exit
2
32
32 degrees Fahrenheit equals 0 degrees Celsius
Enter 1 to convert Celsius to Fahrenheit
Enter 2 to convert Fahrenheit to Celsius
Enter 0 to exit
0
“exit the program”
My issue is that while it will scan my choice, the program ends before I can enter a number to convert.
Below is my code:
#include <stdio.h>
int main(void) {
double userConversionChoice;
double CelsiusToFahrenheitResult;
double FahrenheitToCelsiusResult;
double userConversionNumber;
printf("Enter 1 to convert Celsius to Fahrenheit\n");
printf("Enter 2 to convert Fahrenheit to Celsius\n");
printf("Enter 0 to exit\n");
scanf("%d", userConversionChoice);
if (userConversionChoice == 1) {
scanf("%d", userConversionNumber);
CelsiusToFahrenheitResult = (1.8 * userConversionNumber) + 32.0;
printf("%d degrees Celsius equals %d degrees Fahrenheit", userConversionNumber, CelsiusToFahrenheitResult);
}
else {
if (userConversionChoice == 2) {
scanf("%d", userConversionNumber);
FahrenheitToCelsiusResult = (userConversionNumber - 32.0) / 1.8;
printf("%d degrees Fahrenheit equals %d degrees Celsius", userConversionNumber, FahrenheitToCelsiusResult);
}
else {
printf("exit the program");
}
}
return(0);
}
The immediate issues are:
scanf takes pointers to variables (&x), not variables. That's because a normal function call f(x) cannot modify x (arguments are passed by value).
The %d conversion specifier reads an integer (and expects a corresponding int * argument). Your variables are of type double, so either you need to change them to int or use %lf.
Similarly, printf %d expects an int, not a double. The format specifier for double is %f.
You should check the return value when you use scanf to make sure a value was read successfully. scanf returns the number of input items assigned.
Thus:
int userConversionChoice;
if (scanf("%d", &userConversionChoice) != 1) {
fprintf(stderr, "failed to read input\n");
return EXIT_FAILURE; // EXIT_FAILURE is in <stdlib.h>
}
double userConversionNumber;
if (scanf("%lf", &userConversionNumber) != 1) {
printf("%.2f degrees Celsius equals %.2f degrees Fahrenheit", userConversionNumber, CelsiusToFahrenheitResult);
In the long term, I recommend avoiding scanf for user input altogether. It is hard to use correctly, it makes for confusing user interfaces (e.g. if a user just hits enter, your program will sit there seemingly frozen, but actually still waiting for input in scanf), and it's hard to recover from errors.
For more intuitive behavior, read whole lines of input (using e.g. fgets) and convert them afterwards (using e.g. sscanf or strtod / strtol):
char buf[200];
...
printf("enter a number: ");
fflush(stdout);
if (!fgets(buf, sizeof buf, stdin)) {
return 0; // end-of-input was reached
}
double num = strtod(buf, NULL); // convert input to number
userConversionNumber is a double. You are reading into it using %d which is the conversion specifier for integers.
And you are not using the & (address of) operator when reading into it.
scanf("%d", userConversionChoice);
So define userConversionChoice as an int and read the input this way:
scanf("%d", &userConversionChoice);
Behaviour of scanf:
The scanf function returns the value of the macro EOF if an input failure occurs before the first conversion (if any) has completed. Otherwise, the function returns the number of input items assigned, which can be fewer than provided for, or even zero, in the event of an early matching failure.
So it is good practice to check the return value of scanf before further processing.
Your use of scanf (and printf) is incorrect.
The format string must match the type of parameter you are using. You can get away with this on printf() sometimes, but not scanf().
For scanf(), you must also pass the address-of (i.e.: a pointer to) the variable you wish to store into.
#include <stdio.h>
int main(void)
{
int userConversionChoice;
double CelsiusToFahrenheitResult;
double FahrenheitToCelsiusResult;
double userConversionNumber;
printf("Enter 1 to convert Celsius to Fahrenheit\n");
printf("Enter 2 to convert Fahrenheit to Celsius\n");
printf("Enter 0 to exit\n");
printf("Choice> ");
scanf("%d", &userConversionChoice);
if (userConversionChoice == 1)
{
printf("Temperature> ");
scanf("%lf", &userConversionNumber);
CelsiusToFahrenheitResult = (1.8 * userConversionNumber) + 32.0;
printf("%0.2lf degrees Celsius equals %0.2lf degrees Fahrenheit", userConversionNumber, CelsiusToFahrenheitResult);
}
else if (userConversionChoice == 2)
{
printf("Temperature> ");
scanf("%lf", &userConversionNumber);
FahrenheitToCelsiusResult = (userConversionNumber - 32.0) / 1.8;
printf("%0.2lf degrees Fahrenheit equals %0.2lf degrees Celsius", userConversionNumber, FahrenheitToCelsiusResult);
}
else
{
printf("exit the program");
}
return(0);
}
Obviously there's some room here for optimisation, since there's two lots of code inputting the temperature.
Related
I am new to C and am writing a simple code of converting temperatures. The code is still incomplete but still should give me some output
#include<stdio.h>
void main()
{
float temp;
char choice;
printf("\n 1. Celcius to Farenhite\n 2. Farenhite to Celcius\n What do you want to convert from? : ");
scanf("%c", &choice);
switch (choice)
{
case 1:
printf("Enter temperature in Celcius: ", temp );
scanf("%f", &temp);
break;
case 2:
printf("Enter temperature in Farenhite: ", temp);
scanf("%f", &temp);
break;
default:
printf("Invalid Choice");
break;
}
}
When I run this it asks "what do you want to convert from?" and shows the options. But when I enter 1 or 2, it directly prints and shows "Invalid Choice".
Pls tell me what's wrong :(
1 is 'int' and not a char.
1 and '1' are different.
This is the edited code
#include<stdio.h>
void main()
{
float temp;
char choice;
printf("\n 1. Celcius to Farenhite\n 2. Farenhite to Celcius\n What do you want to convert from? : ");
scanf("%c", &choice);
switch (choice)
{
case '1':
printf("Enter temperature in Celcius: ", temp );
scanf("%f", &temp);
break;
case '2':
printf("Enter temperature in Farenhite: ", temp);
scanf("%f", &temp);
break;
default:
printf("Invalid Choice");
break;
}
}
The number one is not the same as the digit "1". You are entering the character "1" and your switch statement is checking for the number one.
The number one is how many hearts I have. It can be written with the digit '1' but any number of other ways.
The digit '1' is a character. It is sometimes use to represent the number one but can also be used for other things. A variable of type char can hold the digit 1 since digits are characters.
Your switch statement is checking for the number one. You want to check for the character 1.
'1' is a character, whereas 1 is an integer. Your switch statement can't find a case to match with, hence it goes to default.
Is that the complete code? You're not converting anything here, you're only asking the user for the temperature and storing it in a variable.
OT: Indent properly, your code is messy and difficult to read. And do not use scanf for taking input. You may want to check out this link http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html.
This is a common misunderstanding for novices and occasional typo for experienced programmers(*).
1 means "the integer value one" (it is the integer literal for the value of 1).
Assuming your on an ASCII compatible platform(**) that is the character with ASCII code 1 (the non-printing character called Start of Header - SOH).
The ASCII Code for the character 1 is actually 49. But you should write:
case '1':
Because those apostrophes identify the 1 as the character representing 1 not the numeric value of 1.
The compiler will interpret '1' as actually meaning character of 1 meaning the (codepoint) value of 49.
In C char has a deeply dual role as a numeric type and as the smallest unit of text and accidental mixing of those roles causes endless confusion.
Arguably char has 3 roles. The smallest arithmetic type, the smallest unit of text (a character) and the unit of addressable memory (byte).
There are historical reasons why those roles are conflated in C.
(*) But I can't find a good answer for it even though there should be thousands of times this has been asked.
(**) C does not specify a character set but if you working on a platform that isn't ASCII compatible you will know about it. Unless you've found something in your Grandparent's basement and they're sadly not around to explain it. This footnote exists for the likely comments to the effect that C doesn't specify a character set.
Your program reads a byte from stdin and compares that to the values 1 and 2. It is unlikely the user can type these byte values as they correspond to control characters CtrlA and CtrlB1. The byte values representing the digits 1 and 2 typed by the user are noted in C as '1' and '2'. These are called character constants and are int values for the encoding of the corresponding characters.
Furthermore, you should:
indent your code more consistently.
define main with a return type int
test the return value of scanf()
fix the spelling of Fahrenheit, named after German physicist Daniel Gabriel Fahrenheit and Celsius, named after Swedish astronomer Anders Celsius.
1: From a unix terminal, one can actually enter these byte values by hitting CtrlV CtrlA and CtrlV CtrlB, respectively, followed by Enter.
Here is a modified version:
#include <stdio.h>
int main() {
float temp;
char choice;
printf(" 1. Celsius to Fahrenheit\n"
" 2. Fahrenheit to Celsius\n"
" What do you want to convert from? ");
if (scanf(" %c", &choice) != 1)
return 1;
switch (choice) {
case '1':
printf("Enter temperature in Celsius: ", temp);
if (scanf("%f", &temp) != 1)
return 1;
printf("%g degrees Celsius is %g degrees Fahrenheit\n",
temp, 32 + temp * 9 / 5);
break;
case '2':
printf("Enter temperature in Fahrenheit: ", temp);
if (scanf("%f", &temp) != 1)
return 1;
printf("%g degrees Fahrenheit is %g degrees Celsius\n",
temp, (temp - 32) * 5 / 9);
break;
default:
printf("Invalid choice\n");
break;
}
return 0;
}
This program prints overlapping of two intervals. But the problem is, if I enter, for example numbers :
1.1 -1.1 1.1 1.1, it prints out the whole number. I've tried writing %1.1f in last printf command, but it turned out to be even worse, because then, if I enter 1 2 1 1, it prints out 1.0 and 4.0. How can I get the proper print if I enter decimale or int?
#include <math.h>
int main() {
float a,b,c,x,derivative;
printf("Input coefficients a, b i c: ");
scanf("%f %f %f",&a,&b,&c);
if((a<(-10)) || (a>10) || (b<(-10)) || (b>10) || (c<(-10)) || (c>10)){
printf("Coefficients a, b i c do not belong in range of (-10,10).");
return 1;
}
printf("Input point x: ");
scanf("%f",&x);
derivative=(2*a*x)+b+(c*0);
printf("First derivation in point x=%.f je %.f.",x,derivative);
return 0;
}
You can use the "%g" format specifier to display floating-point numbers in the shortest possible way:
printf("First derivation in point x=%g je %g",x,derivative);
I'm trying to take the user input, which is a character string, and convert it to a float. In my case, gas keeps being printed as 55.000000 when the user enters 7 - I'd like it to be printed as 7.0.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
int main()
{
char gas_gallons;
float gas;
printf("Please enter the number of gallons of gasoline: ");
scanf("%c", &gas_gallons);
while (!isdigit(gas_gallons))
{
printf("\nYou need to enter a digit. Please enter the number of gallons of gasoline: ");
scanf("%c", &gas_gallons);
}
if (isdigit(gas_gallons))
{
printf("\nHello %c", gas_gallons);
gas = gas_gallons;
printf("\nHello f", gas);
}
return 0;
}
Why not do this? It's much simpler.
#include<stdio.h>
int main()
{
int gas;
printf("Please enter the number of gallons of gasoline.\n : ");
//use the %d specifier to get an integer. This is more direct.
//It will also allow the user to order more than 9 gallons of gas.
scanf("%d", &gas);
printf("\nHello %d", gas);//prints integer value of gas
//Using the .1f allows you to get one place beyond the decimal
//so you get the .0 after the integer entered.
printf("\nHello %.1f\n", (float) gas);//print floating point
return 0;
}
You said:
In my case, gas keeps being printed as 55.000000 when the user enters 7
When the user enters 7 as input the digit 7 is stored as the character in gas_gallons. The decimal value of the character 7 is 55 in ASCII encoding. You can see the decimal values of other characters in ASCII encoding at Wikipedia and many other places on the web.
When you use:
gas = gas_gallons;
the integer value of gas_gallons is, i.e. 55, is assigned to gas. That explains why you get 55.000000 as the output when you print gas.
You can fix the problem many ways. Here are a couple of suggestions.
Option 1
Convert the digit to a number by using:
gas = gas_gallons - '0';
Option 2
Discard the code to read the number of gallons of gasoline as a digit and converting the digit to a number. Using a digit is also limiting since you cannot have 10 or 12.5 as input.
Read the number of gallons of gasoline as a number directly. With this approach, your input can be a any floating point number that can be represented by a float.
#include <stdio.h>
int main()
{
float num_gallons;
while ( 1 )
{
printf("Please enter the number of gallons of gasoline: ");
// Read the number of gallons of gas.
// If reading is successful, break of the loop.
if (scanf("%f", &num_gallons) == 1 )
{
break;
}
// There was an error.
// Read and discard the rest of the line in the input
// stream.
scanf("%*[^\n]%*c");
printf("There was an error in reading the gallons of gasoline.\n");
}
printf("\nHello %f\n", num_gallons);
return 0;
}
The ASCII-characters '0'-'9' do not have the integer values 0-9. You can find the appropriate value by subtracting '0'.
To convert a string to float you can use atof (ASCII to float) function included in stdlib.h.
Here is the full declaration of this function: double atof(const char *str)
so you can do a simple cast
gas = (float) atof(gas_gallons);
This question already has answers here:
Problems with scanf and doubles [duplicate]
(2 answers)
Closed 8 years ago.
I wrote the following code for an intro to C class. However for some reason I cannot figure out why the scanf will not store the input into the fahrenheit variable therefore not allowing me to do the calculation correctly. I switched the starting value from 0 to 212 to make sure that my calculation is correct however it still doesn't allow me to update.
#include <stdio.h>
int main(void){
double fahrenheit = 212.00;
double celcius = 0;
//prompt the user for the information
printf("Enter a temperature in degrees Fahrenheit >");
//store the information in the Fahrenheit var.
scanf("%f", &fahrenheit);
//calculate the change in metrics
celcius = (fahrenheit-32)*.5556 ;
printf("%f degrees Fahrenheit is equal to %f degrees celcius\n",fahrenheit,celcius);
}
The proper printf and scanf format to use with double argument is %lf. Not %f, but %lf. Don't use %f with double. It should be
scanf("%lf", &fahrenheit);
...
printf("%lf degrees Fahrenheit is equal to %lf degrees celcius\n",
fahrenheit, celcius);
Note that %f will work with double in printf (not in scanf), but using it in that fashion is still a bad habit, which only fuels the popular beginner's misconception that printf and scanf are somehow "inconsistent" in that regard.
The matching between format specifiers and argument types is well-defined and consistent between printf and scanf:
%f is for float
%lf is for double
%Lf is for long double.
You're reading a float (with %f) and yet you're storing it inside a double.
Either
Change the type of fahrenheit to float
Change your scanf call to `scanf("%lf", &fahrenheit);
You declared your variable as double fahrenheit; but used the scanf() specifier for float, try this
#include <stdio.h>
int main(void) {
float fahrenheit = 212.00;
/* ^ float, instead of double */
float celcius = 0;
// prompt the user for the information
printf("Enter a temperature in degrees Fahrenheit > ");
// store the information in the Fahrenheit var.
if (scanf("%f", &fahrenheit) != 1) // check that scanf succeeded
return -1;
// calculate the change in metrics
celcius = (fahrenheit-32)*.5556 ;
printf("%f degrees Fahrenheit is equal to %f degrees celcius\n",fahrenheit,celcius);
return 0;
}
or change the scanf() specifier to "%lf" the printf() specifier is ok for both.
Also, you better make sure scanf() succeeded reading.
I just started programming in C a few days ago and I want to improve my program but not sure how to do it.
This program is a Fahrenheit to Celsius and vice versa converter. I did it in the simplest way possible. But now I want to do it so that I have 2 functions c2f and f2c which take the temperature as a parameter and when I run the program I want do choose whether I want to covert from F to C or from C to F (something like TempConverter -f 32 this should only convert 32 into celsius and TempConverter -c 100 should covert 100 into Fahrenheit).
I think my functions should be something like this : float c2f (float c) and float f2c (float f)
But how exactly do it do it so when I run something like > TempConverter -f 50.0 I get something like this let's say?
10.00°C = 50.00°F
#include<stdio.h>
int main(void)
{
// Local Declarations
float Celsius, Fahrenheit, Fahrenheit_1, Celsius_2;
// Statements
printf("Enter the temperature in Fahrenheit: ");
scanf("%f", &Fahrenheit);
printf("Fahrenheit temperature is: %5.1f F\n\a", Fahrenheit);
Celsius = (100.0 / 180.0) * (Fahrenheit - 32);
printf("Celsius temperature is: %8.1f C\n\n\a", Celsius);
printf("Enter the temperature in Celsius: ");
scanf("%f", &Celsius_2);
printf("Celsius temperature is: %8.1f C\n\a", Celsius_2);
Fahrenheit_1 = 32 + (Celsius_2 * (180.0 / 100.0));
printf("Fahrenheit temperature is: %5.1f F\a", Fahrenheit_1);
return 0;
}
Current output:
*Enter the temperature in Fahrenheit: 20
Fahrenheit temperature is: 20.0 F
Celsius temperature is: -6.7 C
Enter the temperature in Celsius: 40
Celsius temperature is: 40.0 C
Fahrenheit temperature is: 104.0 F*
Desired Output
TempConverter -f 50.0
10.00°C = 50.00°F
The first thing you'll need to do is add command line arguments to your code, like so:
int main( int argc, char **argv )
argc contains the number of parameters entered on the command line; it is always >= 1.
argv contains pointers to each of the command line argument strings. argv[0] always points to the string you used to start the program. argv[argc] is always NULL.
So, if you called your program as
TempConverter -f 50.00
then
argc == 3
argv[0] == "TempConverter"
argv[1] == "-f"
argv[2] == "50.00"
argv[3] == NULL
Note that to use the last parameter in your conversion functions, you'll need to convert it from a string to a floating-point value. strtod is the library function of choice for this:
char *check;
double intemp = strtod(argv[2], &check);
After the conversion, check will point to the first character in the string that was not converted to a floating point value. If this character is something other than whitespace or 0, then the input value was not a valid floating-point string.
So, the general order of operations:
Check the value of argc. For your purposes, it needs to be 3.
Convert argv[2] to a floating-point value using strtod. Make sure the check character is either 0 or whitespace.
Check your fahrenheit/celcius switch; it needs to be either "-f" or "-c" (or whatever you decide on).
Call the appropriate conversion function based on the fahrenheit/celcius switch, and display the result.
You are looking to use commandline arguments that come as arguments to main
int main(int argc, char *argv[])
Here argc corresponds to the number of arguments supplied and the arguments are stored in argv. Note that the name of the program is also considered an argument and is stored in argv[0]. Assuming you expect a flag -f or -c followed by a float, you can use them inside main as follows:
/**
* Check for the expected number of arguments (3)
* (0) program name
* (1) flag
* (2) temperature
*/
if (argc!=3)
printf("Incorrect number of arguments");
if (!strcmp(argv[1], "-f"))
// process from fahrenheit to celsius
else if (!strcmp(argv[1], "-c"))
// process from celsius to fahrenheit
else
printf("Invalid flag\n");
Note, whenever you are dealing with user input, it is very important to check that the input corresponds to what you expect. My suggested code gives some example, but you should think hard about how you can make it even more secure
#include<stdio.h>
main(int argc,char** argv)
{
int result;
printf("\nValue of Celcius: \n");
scanf("%i", &argc);
printf("\n%i Celcius = ", argc);
result = ((argc * 9) /5) + 32;
printf("%i Fahrenheit\n", result);
getchar();
getchar();
return 0;
}