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;
}
Related
I'm currently doing a C course and I have to make a program that prints the sine function for an input x between (0, 1). The thing is, I don't know what I'm doing wrong.
double x;
double result = 0;
printf("Input a number betwen 0 and 1: ");
scanf("%.f", x);
result = sin(x);
printf("\aThe sine of %.8f is %.8f\n", x, result);
system("pause>null");
return 0;
This is the code I wrote; when I try to input 0.5 the machine returns me a "The sine of 0.00000 is 0.0000", but if I declare the variable as 0.5, the program works fine and gives me the correct answer. The error appears when I try to use scanf to input the number, and the activity says I have to input it.
I looked in the internet and I can't find anything, I'm a newbie in this world, I started about 2 weeks ago.
There are two fundamental problems with your scanf("%.f", x); line. First, the %.f format specifier is wrong: the . is not valid for input of this sort, and a double value requires the l (lowercase L) prefix - so use %lf.
Second, the argument corresponding to that format specifier must be the address of a suitable (double) variable.
So, use scanf("%lf", &x); and your program will work.
Enable warnings
double x; scanf("%.f", x); should have warned as "%f" expects a matching float *, not a double.
Use "%lf" to read a double.
Even better, check the scanf() return value to insure valid input occurred.
if (scanf("%lf", &x) == 1) {
result = sin(x);
printf("\aThe sine of %.8f is %.8f\n", x, result);
}
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.
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 think it's obvious I don't understand. How do you tell the computer in C to decide which is the appropriate interest rate and then calculate and display it. This is the best I could come up with and I have to hand this as an assignment tomorrow. I had not clue it would be this difficult.
#include <stdio.h>
int main (void)
{
float time;
float principal;
char response[15];
float rate1, rate2,rate3,rate4;
rate1=.04,rate2=.05,rate3=.06,rate4=.07;
float SimpleInterest1;
float SimpleInterest2;
float SimpleInterest3;
float SimpleInterest4;
SimpleInterest1=principal*time*rate1;
SimpleInterest2=principal*time*rate2;
SimpleInterest1=principal*time*rate3;
SimpleInterest2=principal*time*rate4;
printf("Please enter principal\n");
scanf ("%f",&principal);
printf ("Please enter time\n");
scanf ("%f",&time);
if (principal <= 5000)
{
printf ("%f",&SimpleInterest1);
}
printf ("Do you still want the loan?\n");
scanf ("%s",response);
return 0;
}
As it has been already said: do not forget to ask for principal value using
scanf.
Then, use if-else if-else-statements to know in which interval principal lies.
Then, inside each statement, assign interest to the right value.
Then assign time to the right value (you can scanf it if you have to) before calculating the interest.
Also, check if the interest has to be recomputed each year on the
new debt. If this is the case, then the formula should be
debt = principal * (1 + rate)^time.
You can #include <math.h> to use the pow function that computes the power of a float or a double.
Then just printf("%f", debt);.
Aparté:
Michael Overton's book "Numerical Computing with IEEE Arithmetic" pp.82-86 explains pretty well how to compute a compound interest with a stable algorithm, because the naive way to compute it using pow can involve a loss of accuracy.
First off, these two lines are probably a typo:
SimpleInterest1=principal*time*rate3;
SimpleInterest2=principal*time*rate4;
They should become this:
SimpleInterest3=principal*time*rate3;
SimpleInterest4=principal*time*rate4;
Next, if your asking about i/o (input/output), then here's a basic run through:
You use printf( char *format, ...) to output information.
You use scanf( char *format, ...) to do basic input.
Where format is one of the following (this is the basics):
%s : Argument is expected to be of type char*
%i : Argument is expected to be signed int
%f : Argument is expected to be float (use also for double in printf)
%u : Argument is expected to be unsinged int.
When you use scanf, you should check the return value and clear the input buffer, examples will follow:
void clear_buffer() {
// Note that ch is int not char, this is important
int ch;
while( (ch = getchar()) != EOF && ch != '\n');
}
int answers = 0;
float value = 0.0;
do {
// Scanf returns the recieved number of args that fit the format string
answers = scanf( "%f", &value );
clear_buffer();
if (answers == 0) {
continue;
}
} while (value > -0.1 && value < 0.1);
The above may not work as I mainly work with unsigned integers, but it should provide a good foundation at the very least.
You use if...else if....else to determine the formula to use.
Lastly, you should calculate the SimpleInterest AFTER you get a value for time and principal; the c parser cannot 'see into the future'
At the momemt, i'm learning the C and the basics of the language, but I have a problem with my code. When I multiply two numbers, I cant get the decimals, even I float the numbers I enter.
My code:
int main()
{
double result_met, km;
result_met = km = 0.0f;
/*Display text*/
printf("Enter values of the distance between the two cities in km's\n");
scanf_s("%d", &km);
/*Formular for a simple km conversion*/
result_met = km * 1000.0f;
/*Result print*/
printf("Meter:%d", result_met);
printf("\nWaiting for a character to be pressed from the keyboard to exit.\n");
getch();
return 0;
}
The format specifiers are incorrect - it should be %lf - %d is for int.
scanf_s("%lf", &km);
/*Formular for a simple km conversion*/
result_met = km * 1000.0f;
/*Result print*/
printf("Meter:%lf", result_met);
Format string specifications
The format specifier for double is %lf, not %d
You may as well use a float instead of a double, it saves memory (which is important when you begin to write big programs), then you must use the format specifier %f (the "l" in %lf is for "long", because a double is a long float)
When treating decimals, you want to print only a few decimals on the screen (to avoid the printing of a "2.50000001"), then you can use the format specifier %.3f if you want 3 and only 3 digits printed (3 can be any integer).
for example, the following code :
printf("%.2f\n",3.1415);
has the following output :
3.14
the printf function has many different format specifier, that can be very useful.
Go see the cpluplus.com reference if you want to learn more about it