How to force program to recognize word and stop - c

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

Related

Returning more than one variable in the same function

I just need help with returning two user input floating-point numbers using the same function. Can anyone show me how to return more then one variable? Thanks in advance.
#include <stdio.h>
#define SIDE_1_LABEL 'A'
#define SIDE_2_LABEL 'B'
float getUserValue(float side1, float side2);
int main()
{
float side1,
side2;
side1 = getUserValue(SIDE_1_LABEL);
side2 = getUserValue(SIDE_2_LABEL);
return 0;
}
float getUserValue(float side1, float side2)
{
printf(" Enter a value for Side %c.\n", SIDE_1_LABEL);
printf("> ");
scanf("%f", &side1);
printf(" Enter a value for Side %c.\n", SIDE_2_LABEL);
printf("> ");
scanf("%f", &side2);
return side1, side2;
}
You need to either put the two floats into a struct that the function can return, or pass one (or both) floats in as a pass-by-reference parameter. I would definitely prefer two pass-by-reference parameters in this case.
void getUserValue(float *side1, float *side2) {
printf(" Enter a value for Side %c.\n", SIDE_1_LABEL);
printf("> ");
scanf("%f", side1);
printf(" Enter a value for Side %c.\n", SIDE_2_LABEL);
printf("> ");
scanf("%f", side2);
}
There are other serious issues in your code, such as passing chars A and B in as the float parameters for getUserValue(), and only a single one for each call. You should call getUserValue() as:
int main() {
float side1, side2;
getUserValue(&side1, &side2);
return 0;
}
You don't need to pass in SIDE_1_LABEL and SIDE_2_LABEL, as they are #defined globally and can be accessed directly by getUserValue(). And since you get both values in a single call, you don't need to call getUserValue() twice.
Another approach would be to have getUserValue() get only a single value at a time with:
float getUserValue(char label) {
float side;
printf(" Enter a value for Side %c.\n", label);
printf("> ");
scanf("%f", &side);
return side;
}
then call it twice like you currently do :
side1 = getUserValue(SIDE_1_LABEL);
side2 = getUserValue(SIDE_2_LABEL);

Squared Equation calculator not working in C

Hello guys I started learning C few weeks ago and I am trying to make my first useful program, I am trying to create a squared equation calculator but no matter what I type in the input it always outputs "no solution2" can anyone take a look and help me ?
examples for input :
0 0 0=
1 4 1=
#include <stdio.h>
#include <math.h>
int main()
{
printf("enter a\n");
double a; scanf("%1f", &a);
printf("\nenter b\n");
double b; scanf("%1f", &b);
printf("\nenter c\n");
double c; scanf("%1f", &c);
if (a==0)
{
if (b==0)
{
if (c==0)
printf("x can be every number\n");
else
printf("no solution1\n");
}
else
{
printf("x equals %.2f\n", ((-1)*c) / b);
}
}
else
{
double delta = (b*b)-(4*(a*c));
if (delta>0)
{
double sqrtDlt = sqrt(delta);
printf("x1 = %4.2f\n", (((-1)*b) + sqrtDlt) / 2 * a);
printf("x2 = %4.2f\n", (((-1)*b) - sqrtDlt) / 2 * a);
}
else
printf("no solution2\n");
}
return 0;
}
For double use specifier %l(ell)f not %1(one)f in scanf.
Note that this is one place that printf format strings differ substantially from scanf (and fscanf, etc.) format strings. For output, you're passing a value, which will be promoted from float to double when passed as a variadic parameter. For input you're passing a pointer, which is not promoted, so you have to tell scanf whether you want to read a float or a double, so for scanf, %f means you want to read a float and %lf means you want to read a double.

in C, trying to use a program that converts Fahrenheit to kelvin [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 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".

Keeping getting 0.00 as an answer

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?

How to make an answer a floating number or integer depending on the number entered?

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

Resources