I just started programming in C a few days ago and have a few questions:
The following program converts Celsius into Fahrenheit and vice versa. I am getting a Segmentation fault error.
#include<stdio.h>
#include <string.h>
#include<stdlib.h>
float c2f(float);
float f2c(float);
float Fahrenheit,Celsius;
int main(int argc, char *argv[])
{
/**
* 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"))
{
// convert the string into a floating number
char *check;
float Celsius = strtod(argv[2], &check);
// process from celsius to fahrenheit
Fahrenheit = c2f(Celsius);
printf("%5.2f°C = %5.2f°F",Celsius, Fahrenheit);
}
else if (!strcmp(argv[1], "->c"))
{
// convert the string into a floating number
char *check;
float Fahrenheit = strtod(argv[2], &check);
// process from fahrenheit to celsius
Celsius = f2c(Fahrenheit);
printf("%5.2f°F = %5.2f°C", Fahrenheit, Celsius);
}
else
printf("Invalid flag\n");
} // main
float c2f(float c)
{
return 32 + (c * (180.0 / 100.0));
}
float f2c(float f)
{
return (100.0 / 180.0) * (f - 32);
}
Also, I want my output to be like this:
**> TemperatureConverter ->f 10.0
10.00°C = 50.00°F**
This should convert 10C into F.
For F to C, the output should be:
TemperatureConverter ->c 50.0
50.00°F = 10C**
the error is
if (!strcmp(argv[1], "->f")
it's missing a final parenthesis, should be
if (!strcmp(argv[1], "->f"))
and you made the same mistake twice. 1 paren for strcmp(), 1 for if()
you should include string.h. Also, you should put you functions f2c and c2f before main.
also you wrote
prinf
try with a t before the f
printf
finally you need
exit(0);
after the first if. eg
if (argc!=3)
{
printf("Incorrect number of arguments");
exit(0);
}
otherwise the rest of the program runs and you get seg fault. Welcome to programming.
Slight nitpicking:
float c2f(float);
float f2c(float);
While it's technically correct, remember to include the variable name as well in your function declarations. It makes it easier to read.
As an example
float c2f(float c);
I used this code :
/* Declare Initial library for functions */
#include<stdio.h>
#include<conio.h>
/* Main function*/
void main()
{
/* data type(float),variable(c,f)*/
float c, f;
/* printf function from stdio.h library , for printing level*/
printf("Enter temp. in Celsius: ");
/* scanf for inserting data in variable*/
scanf("%f",&c);
/* Fahrenheit rules*/
f = c * 9/5 + 32;
/* Result will display in this line */
printf("Temp. in Fahrenheit: %f",f);
/* getch function from conio.h library, used to write a character to screen*/
getch();
}
Related
I have a problem related to different types of variables at the input type.
My program is simple. I type the temperature in Celsius, program prints Celsius and Fahrenheit temperature value and then loops itself asking for next value in Celsius. If you type "-99999" it will stop.
I wanted to change it to stop when I type a word "elo" (It basically means "Bye" in Polish slang :) ) but after a few hours of trying I gave up...
I'll appreciate any help!
#include <stdio.h>
float fahrenheit(long);
int main()
{
int celsius;
printf("Type the temperature in celsius: ", &celsius);
scanf_s("%ld", &celsius);
while (celsius != -99999) {
printf("%ld %6.1f\n", celsius, fahrenheit(celsius));
printf("Type the temperature in celsius: ", &celsius);
scanf_s("%ld", &celsius);
}
}
float fahrenheit(long celsius)
{
return (float) 1.8*celsius + 32.0;
}
There are a number of ways to do this. I think the easiest is to detect scanf failed to read a number and then fall back on string input.
int celcius;
char buff[10];
bool elo = false;
int args_read = scanf(" %d", &celcius);
if (args_read < 1) {
// User must have put in a non-number
scanf(" %s", buff);
if (strcmp(buff, "elo") == 0) {
elo = true;
}
}
The line printf("Type the temperature in celsius: ", &celsius); is strange. Didn't your compiler complain about this? Why are you providing the address of celsius as an argument to this call? Another mistake is scanf_s("%ld", &celsius);, which reads in celsius as a long int value, when you have only declared celsius as an int. It's a good idea to always enable compiler warnings when you're working on code.
As mentioned by #StephenDocy, you need to read in the input as a string first, then check to see if it is a number or your stop word.
You can also simplify your code a bit to avoid repeating lines like printf("Type the temperature in celsius: ", &celsius); more than necessary. I think it would also make sense to treat celsius as a floating point value
#include <stdio.h>
#include <string.h>
float fahrenheit(float);
int main() {
float celsius;
char input_buffer[256];
while (1) {
printf("Type the temperature in celsius:\n");
scanf("%255s", input_buffer);
if (strcmp("elo", input_buffer) == 0) break;
if (sscanf(input_buffer, "%f", &celsius) == 1) {
printf("%6.1f %6.1f\n", celsius, fahrenheit(celsius));
}
}
return 0;
}
float fahrenheit(float celsius) {
return 1.8 * celsius + 32.0;
}
I have written the following code
#include <stdio.h>
#include <stdlib.h>
int main()
{
// declaration of variables as strings
char astr;
char bstr;
char cstr;
/* Input three sides of a triangle */
printf("Enter first side of triangle: ");
scanf("%s",&astr);
printf("Enter second side of triangle: ");
scanf("%s",&bstr);
printf("Enter third side of triangle: ");
scanf("%s",&cstr);
// conversion of strings to float
float a = atof(&astr);
float b = atof(&bstr);
float c = atof(&cstr);
// checking if given triangle is valid
if((a + b > c) && (a + c > b) && (b + c > a))
{
// Checking for special cases of triangle
if(a==b && b==c)
{
/* If all sides are equal */
printf("Equilateral triangle.");
}
else if(a==b || a==c || b==c)
{
/* If any two sides are equal */
printf("Isosceles triangle.");
}
else
{
/* If none sides are equal */
printf("Scalene triangle.");
}
}
else
{
printf("Triangle is not valid. \n");
}
printf("%f \n", a);
printf("%f \n", b);
printf("%f \n" ,c);
return 0;
}
However when I run it, I get "Triangle is not valid" despite the fact that mathematically the triangle would be valid
When printing the Values stored in a b and c I discover that only the Value for c is stored correctly but a and b are always 0.000000
what have I done wrong?
Thanks in advance
instead of 3 wrong lines:
char astr;
scanf("%s",&astr);
float a = atof(&astr);
let me propose working lines:
char astr[20]; // should be enough
scanf("%19s",astr); // 19 protects from buffer overflow on astr
float a = atof(astr);
First, you cannot scan a string into a char: not enough room / undefined behaviour. Pass a char array instead (and in that case drop the &, it's already an address)
Second, pass the string to atof, not the pointer on the string.
Aside: atof doesn't check for errors, better use strtof which provides (optional) error checking.
int main () {
float val;
char str[10];
strcpy(str, "1234");
val = atof(str);
printf("%f", val);
return 0;
}
You can also use strtod() refer man page of atof()
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 6 years ago.
Improve this question
But the calculation doesn't work or change when I run it and plug in any random number...need some guidance. I'm a novice to C and programming in general so please include easy to understand help.
#include <stdio.h>
double const change_celcius = 32.0;
double const change_kelvin = 273.15;
void temperatures(double n);
int main(void)
{
int q = 'q';
double user_number;
printf("Enter the fahrenheit: \n");
scanf("%f", &user_number);
while (user_number != q)
{
temperatures(user_number);
printf("\n");
printf("Enter the fahrenheit: \n");
scanf("%f", &user_number);
}
}
void temperatures(double n)
{
double celsius, kelvin;
celsius = 5.0 / 9.0 * (n - change_celcius);
kelvin = 5.0 / 9.0 * (n - change_celcius) + change_kelvin;
printf("fahrenheit: %.2f - celsius is: %.2f - kelvin is: %.2f",
n, celsius, kelvin);
}
I don't believe the all the use %lf instead of %f comments, by themselves, fix your program. The handling of q (for "quit") is also problematic so let's fix that too. First, we'll use POSIX function getline() to read it into a string and test if it's "q". If not, we'll sscanf it into a double and use it as our temperature:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
double const change_celsius = 32.0;
double const change_kelvin = 273.15;
void temperatures(double n)
{
double celsius = 5.0 / 9.0 * (n - change_celsius);
double kelvin = 5.0 / 9.0 * (n - change_celsius) + change_kelvin;
printf("fahrenheit: %.2f - celsius is: %.2f - kelvin is: %.2f\n", n, celsius, kelvin);
}
int main(void)
{
char *user_string = NULL;
ssize_t user_string_length;
size_t user_string_capacity = 0;
while (1)
{
printf("Enter the fahrenheit: ");
if ((user_string_length = getline(&user_string, &user_string_capacity, stdin)) < 1)
break;
if (strncmp(user_string, "q\n", (size_t) user_string_length) == 0)
break;
double user_number;
if (sscanf(user_string, "%lf", &user_number) == 1)
temperatures(user_number);
}
if (user_string != NULL)
free(user_string); // free memory allocated by getline()
if (user_string_length == -1)
putchar('\n'); // output courtesy newline if user used ^D to exit
return(0);
}
We check the return value of sscanf so that bad input won't cause the program to recalculate using the last good input. Instead, it will just prompt again for input.
You need to use "%lf" in scanf() and print() to read and write the value of type double.
Note that the printf() will work with "%f" too.
For more details please refer : Why does scanf() need "%lf" for doubles, when printf() is okay with just "%f"?
There are several issues that can be addressed in your code. First, always (Always, in case it wasn't clear) check the return of scanf. That is the only way you know whether the expected number of conversions took place -- and whether you have an actual value to work with in your code.
The return also holds the key to exiting the loop when the user enters 'q' (or anything that causes the conversion to double to fail). By simply checking
if (scanf(" %lf", &user_number) == 1)
You can determine whether to process the value as a temperature, or tell the user has indicated exit.
Another tip, never (Never) write:
printf ("\n");
Why would you want to call a variadic function simply to output a single char? That is what putchar (or fputc) is for, e.g.:
putchar ('\n');
Putting those pieces together, and noting that %lf is used as the format specifier for double, you can rewrite your code, and format the output in quite a bit fewer lines, e.g.
#include <stdio.h>
double const change_celcius = 32.0;
double const change_kelvin = 273.15;
void temperatures (double n);
int main(void)
{
double user_number;
while (printf ("\nEnter temp in degrees fahrenheit: ") &&
scanf(" %lf", &user_number) == 1)
temperatures(user_number);
return 0; /* main() is type 'int' and returns a value to the shell */
}
void temperatures (double n)
{
double celsius, kelvin;
celsius = 5.0 / 9.0 * (n - change_celcius);
kelvin = 5.0 / 9.0 * (n - change_celcius) + change_kelvin;
printf(" fahrenheit: % 7.2lf\n celsius is: % 7.2lf\n kelvin is : % 7.2lf\n",
n, celsius, kelvin);
}
Example Use/Output
$ ./bin/temps
Enter temp in degrees fahrenheit: 212
fahrenheit: 212.00
celsius is: 100.00
kelvin is : 373.15
Enter temp in degrees fahrenheit: 0
fahrenheit: 0.00
celsius is: -17.78
kelvin is : 255.37
Enter temp in degrees fahrenheit: 68
fahrenheit: 68.00
celsius is: 20.00
kelvin is : 293.15
Enter temp in degrees fahrenheit: q
Always compile your code with at minimum -Wall -Wextra warnings enabled (and if you really want to drill down, add -pedantic). Read the warnings and fix them. All of your code should compile without warning before you consider your code reliable at this stage of the game.
Look all answers over, and let me know if you have any questions.
To read Double use %lf instead of %f.
for double printf() will work with %f also.
The calculation seems to be okay; however the you are not reading in the words properly
scanf("%f", &user_number);
You are stating you are reading in a float, yet you are declaring user_name as a double. If you wanted to use a float, you would need to change the user_name declaration from double to float. If you wanted to use a double use "%f".
I keep receiving 0 as my answer at the end. Please help
#include <stdio.h>
int Fahrenheit = 0;
double Celsius = 0.0;
double main(void)
{
printf("This program will convert the temperature from fahrenheit to celsius.\n");
printf("Please type in the temperature in fahrenheit followed by the enter key.\n");
scanf("%d%",&Fahrenheit);
Celsius = (5/9) * (Fahrenheit-32) ;
printf("Your temperature in celsius is %3.2f.\n", Celsius);
return(0);
}
Because of integer division, change 5 / 9 to 5.0 / 9.0. Also, make Fahrenheit double and change scanf() to
if (scanf("%lf", &Fahrenheit) == 1)
{
Celcius = 5.0 * (Fahrenheit - 32.0) / 9.0;
printf("Your temperature in celsius is %3.2f.\n", Celsius);
}
Also:
There is absolutely no reason to make your variables global.
I have seen many peculiar main() signatures and now
double main(void);
Ignoring the return value of scanf() would lead to potential undefined behavior. If I had a teacher that forbids if statements but requires scanf() I would quit with him and find a good instructor.
But of course if I was learning how would I know that ignoring ٰscanf()'s return value is bad? And that's the sad part, many even don't know that it returns a value or that it fails, for instance try this
int value;
if (scanf("%d", &value) != 1)
fprintf(stderr, "Error, invalid input\n");
else
fprintf(stdout, "Ok, so your input is `%d'\n", value);
type "abcd" instead of a number, what happens?
Currently working on an assignment and a bit stuck. We are to convert a temperature from Celsius to Fahrenheit. The final answer should output a floating point number if the answer is a decimal, or a integer if it's a whole number. I have it set up to give me the floating point number, but when I enter a number, say '98.6', I'll get 37.00000 rather than 37. Been at it for a few hours trying to combat it on my own but I've run out of ideas. Thanks for the assistance!
int main(void)
{
float ftemp;
float ctemp;
printf ("Enter a temperature in Fahrenheit: ");
scanf ("%f", &ftemp);
ctemp = (100.0 / 180.0) * (ftemp - 32);
printf ("In Celsius, your temperature is %f!\n", ctemp);
return 0;
}
There really isn't a good way to do this as you have described. What it really sounds like you want is better string formatting. Try using %g instead of %f in your printf (per this post).
e.g.
printf ("In Celsius, your temperature is %g!\n", ctemp);
Now, if you are hell bent on getting it to use an integer, the closest you can come is with:
int main(void)
{
float ftemp;
float ctemp;
int ctempi;
printf ("Enter a temperature in Fahrenheit: ");
scanf ("%f", &ftemp);
ctemp = (100.0 / 180.0) * (ftemp - 32);
ctempi = (int)ctemp;
if(ctemp == ctempi) {
printf("In Celsius, your temperature is %d\n", ctempi);
} else {
printf ("In Celsius, your temperature is %f!\n", ctemp);
}
return 0;
}
You are printing your number as a float, to print it as an integer:
printf ("In Celsius, your temperature is %d!\n", (int) ctemp);
It uses the d conversion specifier for decimal print and the argument is casted to int as %d requires an int.
One thing that's tricky about floating point numbers is that they're not exact. A number that can be expressed in decimal without repeating digits might have repeating digits in binary.
So you need to check if the result is an integer, however due to the imprecise nature of floating point something like (1.0 / 3.0 * 3) == 1 might evaluate to false. So you need to see if it's within some threshold of an integer.
if (fabs(ctemp - roundf(ctemp)) < 0.0001) {
// result is close enough to an integer, so print as integer
printf ("In Celsius, your temperature is %d!\n", (int)ctemp);
} else {
// result is not an integer, so print as a float
printf ("In Celsius, your temperature is %f!\n", ctemp);
}
Read input as a string and test for integer-ness.
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
struct dual {
char type;
union {
int i;
float f;
} u;
} dual_T;
dual_T GetNumber(void) {
dual_T number;
float f;
char buf[100];
if (fgets(buf, sizeof buf, stdin) == NULL) {
number.type = 'n';
return number;
}
// test for float - sample code possibility
int n = 0;
sscanf(buf, "%f %n", &f, &n);
bool f_possible = n > 0 && *n == 0;
// test for int - sample code possibility
n = 0;
sscanf(buf, "%i %n", &number.u.i, &n);
bool i_possible = n > 0 && *n == 0;
if (f_possible) {
if (i_possible) {
// If fits as an `int`, go with `int` as likely higher precision.
if (f >= INT_MIN && f <= INT_MAX) {
number.type = 'i';
return number;
}
}
number.type = 'f';
number.u.f = f;
} else {
if (i_possible) {
number.type = 'i';
} else {
number.type = 'n'; // none
}
}
return number;
}