Why is printf working but scanf isn't? - c

Alright so I have to create a weather program and when I try running the code, I get no errors but it will just print the "enter a starting temperature" and the "enter an ending temperature". However it won't let me input the data for it. Is there anything I need to change? I know I haven't completed the code but I just wanted to test out the inputs before continuing with the rest of the code. Thanks for the help!
#include <stdio.h>
int main(int argc, char **argv)
{
float celcius, fahrenheit, kelvin, ending, interval;
int c, f, k, temp;
printf("which temperature is being input? (C,F,K) ");
scanf("%d", &temp);
if (temp == c)
{
printf("enter a starting temperature");
scanf("%f", &celcius);
printf("enter an ending temperature");
scanf("%f", &ending);
fahrenheit = celcius * 9 / 5 + 32;
kelvin = celcius + 273.15;
}
if (temp == f)
{
printf("enter a starting temperature");
scanf("%f", &fahrenheit);
celcius = fahrenheit - 32 * 5 / 9;
kelvin = fahrenheit - 32 * 5 / 9 + 273.15;
printf("enter an ending temperature");
scanf("%f", &ending);
if (temp == k)
{
}
printf("enter a starting temperature");
scanf("%f", &kelvin);
fahrenheit = kelvin - 273 * 1.8 + 32;
celcius = kelvin - 273.15;
printf("enter an ending temperature");
scanf("%f", &ending);
}
}

This:
if (temp == c)
is comparing the newly-read value in temp to the undefined value in the uninitialized variable c. This is undefined behavior.
You probably meant
if (temp == 'c')
to compare against a character, but then you also need:
char temp;
if (scanf("%c", &temp) == 1)
{
if (temp == 'c')
{
/* more code here */
}
}
Note that checking the return value of scanf() helps make the program more robust, and avoids further uses of uninitialized values (if scanf() fails to read something, you shouldn't read the destination variable since it won't have been written to).

if (temp == c)
You are comparing temp with an uninitialized value of c
same for
if (temp == f)
then every thing will be working fine , to make it more user friendly , put a '\n' in printf's
like this,
printf("enter a starting temperature \n");

Here:
printf("which temperature is being input? (C,F,K) ");
scanf("%d", &temp);
you ask for a character to be input, but then you try to scan for an int. This will throw off all the rest of your scanf() calls.

Your variable temp is declared as an integer. Indeed, scanf() wants to read an integer (%d), but gets a char.
Therefore, you read temp as a char.
Furthermore you may use
9.0/5.0
instead of
9/5
Furthermore, using the switch statement would increase the readability.

Related

Can't figure out the problem in this Fahrenheit to Celsius converter written in C

I think due to while loop the fahr variable is changing everytime the loop is executed and because of that the variable conv is changing. But I don’t know how to fix it. So can anyone please help me out?
#include<stdio.h>
main() {
int n,step;
float fahr,cel,conv;
conv=fahr+(n*step);
printf("This program makes 'n' number of list for fahrenheit to celcius converted numbers.\n");
printf("Please enter the number that is 'n'- \n");
scanf("%d",&n);
printf("\nPlease enter the fahrenheit value- \n");
scanf("%f",&fahr);
printf("\nPlease enter step count- \n");
scanf("%d", &step);
printf("\nFahrenheit\tCelcius\n");
cel=((float)5/(float)9)*(fahr-32);
while(fahr<=conv){
printf("%f\t%f\n",fahr,cel);
fahr=fahr+step;
};
}
EDIT -
So heres the updated version I wrote. This version can do two types of conversion now and it can restart the program.
#DavidC.Rankin can you please check this one and suggest me what should I change? I didn't use fputs because I don't know how it works. Thanks a lot.
#include <stdio.h>
int main()
{
int n, step, i, conv ;
double fahr, cel ;
start:
puts("\nThis program can make 'n' number of lists of two type of conversions-\n\n(1) Fahrenheit to Celcius conversion\n\n(2) Celcius to Fahrenheit conversion\n");
puts("Which type of conversion would you like to use?\n(please enter the number)\n");
scanf("%d",&i);
if(i==1){
puts("\nThis program makes 'n' number of list for \n'Fahrenheit to Celcius converted numbers'\nstarting from the given Fahrenheit value.\n");
puts("Please enter the value of 'n'- ");
scanf("%d", &n);
puts("\nPlease enter the Fahrenheit value- ");
scanf("%lf", &fahr);
puts("\nPlease enter step count- ");
scanf("%d", &step);
puts("\n\tFahrenheit\tCelcius"
"\n\t----------\t-------");
conv = fahr + (n * step);
cel = (5. / 9.) * (fahr - 32);
while (fahr <= conv)
{
printf("\t%lf\t%lf\n",fahr,cel);
fahr = fahr + step;
cel = (5. / 9.) * (fahr - 32);
};
goto again;
}
else if(i==2){
puts("\nThis program makes 'n' number of list for \n'Celcius to Fahrenheit converted numbers'\nstarting from the given Celcius value.\n");
puts("Please enter the value of 'n'- ");
scanf("%d", &n);
puts("\nPlease enter the Celcius value- ");
scanf("%lf", &cel);
puts("\nPlease enter step count- ");
scanf("%d", &step);
puts("\n\tCelcius\tFahrenheit"
"\n\t-------\t----------");
conv = cel + (n * step);
fahr = ((9. * cel) / 5.) + 32;
while (cel <= conv)
{
printf("\t%lf\t%lf\n",cel,fahr);
cel = cel + step;
fahr = ((9. * cel) / 5.) + 32;
};
goto again;
}
else{
puts("Invalid Input! Please try again\n\n\n\n");
goto start;
};
again:
puts("Would you like to restart the program?\n"
"\tyes=1 no=0\n");
scanf("%d",&i);
if(i == 1){
goto start;
}
else if(i == 0){
puts("The program has ended.");
}
else{
puts("Wrong Input!\n");
goto again;
};
}
You have two-primary problems and a number of minor issue. #hanie has already pointed out where you used variables with automatic storage duration while their values were indeterminate in:
conv=fahr+(n*step);
The second issue that will prevent you from ever getting any interesting output is you fail to update the value of cel within your loop. That means that the same value for cel will be output no matter what the value of fahr is. You need to calculate a new cel after you update the value for fahr, e.g.
cel = 5./9. * (fahr - 32);
while (fahr <= conv) {
printf ("% 2g\t\t% 8.2f\n", fahr, cel);
fahr = fahr + step;
cel = 5./9. * (fahr - 32); /* you must update cel within the loop */
}
You invite Undefined Behavior by failing to validate your user input succeeds. You cannot use any user-input function correctly unless you check the return. For scanf the return is the number of successful conversions that took place. In each case you are attempting 1-conversion, so you must check the return of each call to scanf to determine if it is 1 indicating a successful conversion. Otherwise, a matching failure will leave the character causing failure unread in stdin resulting in all of your variables having indeterminate values even after the attempted inputs invoking undefined behavior. Take the time and check the return, for EVERY user-input.
Putting it altogether and eliminating the unnecessary casts and changing type float to double, and eliminating printf for all outputs where no conversion is required, you would have:
#include<stdio.h>
int main (void) {
int n, step;
double fahr, cel, conv;
/* there is no conversion -- printf isn't needed, use puts */
puts ("This program makes 'n' number of list for fahrenheit "
"to celcius converted numbers.\n");
puts ("Please enter the number that is 'n'-");
if (scanf ("%d", &n) != 1) { /* validate EVERY user-input */
fputs ("error: invalid integer input.\n", stderr);
return 1;
}
puts ("\nPlease enter the fahrenheit value-");
if (scanf ("%lf", &fahr) != 1) { /* validate EVERY user-input */
fputs ("error: invalid double input.\n", stderr);
return 1;
}
puts ("\nPlease enter step count-");
if (scanf ("%d", &step) != 1) { /* validate EVERY user-input */
fputs ("error: invalid integer input.\n", stderr);
return 1;
}
conv = fahr + (n * step);
puts ("\nFahrenheit Celcius\n"
"----------- --------");
cel = 5./9. * (fahr - 32);
while (fahr <= conv) {
printf ("% 2g\t\t% 8.2f\n", fahr, cel);
fahr = fahr + step;
cel = 5./9. * (fahr - 32); /* you must update cel within the loop */
}
}
(note: a good compiler with make the printf -> puts optimization for you, but show an understanding of how to handle output in C by using the correct function where no value conversion is required)
Example Use/Output
A simple example listing all values for Fahrenheit from 20 t0 40 by 1 would result in:
$ ./bin/cf
This program makes 'n' number of list for fahrenheit to celcius converted numbers.
Please enter the number that is 'n'-
20
Please enter the fahrenheit value-
20
Please enter step count-
1
Fahrenheit Celcius
----------- --------
20 -6.67
21 -6.11
22 -5.56
23 -5.00
24 -4.44
25 -3.89
26 -3.33
27 -2.78
28 -2.22
29 -1.67
30 -1.11
31 -0.56
32 0.00
33 0.56
34 1.11
35 1.67
36 2.22
37 2.78
38 3.33
39 3.89
40 4.44
Let me know if you have further questions.
you are using uninitialized variables in this line conv=fahr+(n*step);
this line should be here:
main() {
int n, step;
float fahr, cel, conv;
printf("This program makes 'n' number of list for fahrenheit to celcius converted numbers.\n");
printf("Please enter the number that is 'n'- \n");
scanf("%d", &n);
printf("\nPlease enter the fahrenheit value- \n");
scanf("%f", &fahr);
printf("\nPlease enter step count- \n");
scanf("%d", &step);
printf("\nFahrenheit\tCelcius\n");
conv = fahr + (n * step);
cel = ((float)5 / (float)9) * (fahr - 32);
while (fahr <= conv) {
printf("%f\t%f\n", fahr, cel);
fahr = fahr + step;
cel = 5./9. * (fahr - 32);
};
}
also as #David C. Rankin said in comment, you should add cel = 5./9. * (fahr - 32) as the last expression in the while loop. Otherwise cel is never updated. and so while fahr changes, you will have same value in cel.
also pay attention to the way of scanning data which #David C. Rankin said in comment.use this instead of scanf("%d",&n);
(if (scanf("%d", &n) != 1)
{
fputs ("error: invalid integer value.\n", stderr);
return 1;
}
for checking success of taking input.

Confusion with scanf() or if()

I am not so familiar with C. Therefore, maybe someone will easily find a solution, I will not mind if you share it.
After entering the data in the first scanf() always gives the option else(): "Error".
I was looking for possible options for the problem. I found a lot of things like that, but nothing that to help me specifically. I think the mistake is in the strcmp(). But I can not say for sure. Will you help?
#include <stdio.h>
#include <string.h>
int main()
{
float celsius, fahrenheit;
char tempConvering[10];
printf("Enter what to convert to what (F to C; C to F): ");
scanf(" %s", &tempConvering[10]);
if(strcmp(tempConvering, "F to C") == 0)
{
printf("\nEnter temperature in Fahrenheit: ");
scanf(" %f", &fahrenheit);
celsius = fahrenheit * 1.8 + 32;
printf("%.2f Fahrenheits = %.2f Celsius\n", fahrenheit, celsius);
}
else if(strcmp(tempConvering, "C to F") == 0)
{
printf("\nEnter temperature in Celsius: ");
scanf(" %f", &celsius);
celsius = (fahrenheit - 32) / 1.8;
printf("%.2f Celsius = %.2f Fahrenheits\n", celsius, fahrenheit);
}
else
{
puts("\nError!");
}
}
I believe there's an error with how you're using scanf, specifically, at this point:
scanf(" %s", &tempConvering[10]);
^
|
+---- here
The second argument to scanf should be the address of the place to store the result. Here, you're saying "place the string that's read in in the memory just after the buffer that I've set up," which isn't probably want you wanted to do. Instead, write this:
scanf(" %s", tempConvering);
This says "place the string inside the buffer named tempConverting." If you're just getting started with C and haven't learned much about pointers and arrays, a good rule of thumb is that if you're reading a string with `scanf, you should just give the name of the array variable where you want to store the string rather than using an ampersand.
Hope this helps!
#include <stdio.h>
#include <string.h>
int main()
{
float celsius, fahrenheit;
char tempConvering[20];
printf("what do you want to convert? ");
scanf("%s", tempConvering);
if(strcmp(tempConvering, "Fahrenheits") == 0)
{
printf("Enter temperature in Fahrenheit: ");
scanf("%f", &fahrenheit);
celsius = (fahrenheit - 32) / 1.8;
printf("%.2f Fahrenheits = %.2f Celsius\n", fahrenheit, celsius);
}
else if(strcmp(tempConvering, "Celsius") == 0)
{
printf("Enter temperature in Celsius: ");
scanf("%f", &celsius);
fahrenheit = celsius * 9 / 5 + 32;
printf("%.2f Celsius = %.2f Fahrenheits\n", celsius, fahrenheit);
}
else
{
puts("\nError!");
}
}
This was the answer. I have to thank you for the tips, I will try to remember all the details about the scanf(). However, the problem disappeared only when I changed the desired answer not to "F to C" but to "Fahrenheits". Well, respectively, I changed the question. The program instantly earned. Nevertheless, attempts to do something with the scanf() are unsuccessful, to the extent that the same thing happens with the fgets().
In any case, somehow the problem is solved, thank you all!
Don't put extra space while you execute the scanf() function.
This might be an issue sometimes!
This should work fine:
scanf("%s", tempConvering);
By the way, while you take a string as an input, there is no need to use & before the string name.
Someone has already described the details above.

Compare strings in C using getchar

I know this has been asked before and I've read through the answers. I also know that my code isn't great as I'm still learning C. I'm trying, without any luck, to compare a user entered char with a char in an if statement. All and any advice is appreciated. Also, I'm aware of buffer issues though just trying to get the comparison to work first.
#include <stdio.h>
#include <math.h>
#include <string.h>
int main(void){
//int n;
//const char *F = "F";
//float temp;
//float converted;
printf("Would you like to enter Fahrenheit or Celcius? Please type F or C: ");
//scanf("%c", &a);
char input = getchar(); //This will get a single Char from the user and keep it as a char
printf("%c\n", input);
//n = strcmp(input, F);
if(input == "C") {
printf("Please enter the temp you would like to convert to Fahrenheit: ");
scanf("%f", &temp);
converted = temp * 9/5 +32;
printf("You entered %2f Celcius and that equals %2f Fahrenheit\n", temp, converted);
}else if(strcmp(input, "f") == 0) || (strcmp(input, "F") == 0){
printf("Please enter the temp you would like to convert to Celcius: ");
scanf("%f", &temp);
}else{
printf("You didn't enter F or C");
}
}
int strcmp ( const char * str1, const char * str2 );
strcmp takes two string variables.
but your input variable is a char. So use if(input == 'C') and if(input == 'F')
You are comparing characters so it should be input=='C'.
By the way don't forget to put dummy getchar() so that the \n doesn't come into the input character.
Also you are using char input in strcmp().
You have not declared temp or converted.
Note: In C you can't compare strings by using ==.
Corrected code
#include <stdio.h>
#include <math.h>
#include <string.h>
int main(void){
//int n;
//const char *F = "F";
float temp;
float converted;
printf("Would you like to enter Fahrenheit or Celcius? Please type F or C: ");
//scanf("%c", &a);
char input[10];// = getchar(); //This will get a single Char from the user and keep it as a char
scanf("%s",input);
printf("%s\n", input);
//n = strcmp(input, F);
if(strcmp(input,"C")==0) {
printf("Please enter the temp you would like to convert to Fahrenheit: ");
scanf("%f", &temp);
converted = temp * 9/5 +32;
printf("You entered %2f Celcius and that equals %2f Fahrenheit\n", temp, converted);
}else if((strcmp(input, "f") == 0) || (strcmp(input, "F") == 0)){
printf("Please enter the temp you would like to convert to Celcius: ");
scanf("%f", &temp);
}else{
printf("You didn't enter F or C");
}
}

C - printf inside "if" statement doesn't show

I'm trying to make this printf inside the if statement show, but it doesn't. Here is the code, I've highlighted the printf section.
char conv;
float cel;
printf("Enter what you'd like converted: \n\t1.Celcius to Fahrenheit\n\t2.Inch to CM\n\t3.CM to Inch\n");
scanf_s("%c", &conv);
// This one
if (conv == '1')
printf("Please enter amount of Celcius: \n");
scanf_s("%f", &cel);
float fahr;
fahr = 33.8 * cel;
printf("Conversion of %f Celsius is %f Fahrenheit", cel, fahr);
getch();
return 0;
What is the reason for this?
In looking at the line: scanf_s("%c", &conv);
I see the function scanf_s(),
which in not in any C library that I'm familiar with.
However, the function scanf(), which is in the C libraries,
has the following prototype and usage:
int scanf(const char *format, ...)
where the return value is the number of items in the variable parameter list '...'
that were actually filled from the input.
I.E. your code should, after the call to scanf_s() check the return code
those value should be 1 in your example.
Then you have this code:
if (conv == '1')
printf("Please enter amount of Celcius: \n");
scanf_s("%f", &cel);
supposedly with the idea that all those following lines would be
enclosed in the 'if' block.
however, only the first line following the 'if' is actually part of the
'if' block.
To correct this problem, write the code using braces to delineate
the 'if' block, like this:
if (conv == '1')
{
printf("Please enter amount of Celcius: \n");
scanf_s("%f", &cel);
float fahr;
fahr = 33.8 * cel; // BTW: this is not the correct conversion formula
printf("Conversion of %f Celsius is %f Fahrenheit", cel, fahr);
}

Math equation won't be read. Why is this?

Sorry for not adding the whole code. Dumb mistake on my part.
#include <stdio.h>
int main(int argc, char ** argv) {
float celcius, fahrenheit, kelvin, interval;
int c, f, k;
char temp;
printf("which temperature is being input? (C,F,K) ");
scanf("%s", &temp);
if(temp == 'c') {
printf("enter a starting temperature");
scanf("%f", &celcius);
fahrenheit=celcius*9/5+32;
kelvin=celcius+273.2;
printf("%f, %f, %f", celcius, fahrenheit, kelvin);
}
else if(temp == 'f') {
printf("Please enter a starting temperature");
scanf("%f", &fahrenheit);
celcius=fahrenheit-32*5/9;
kelvin=fahrenheit-32*5/9+273.2;
printf("%f, %f, %f", celcius, fahrenheit, kelvin);
}
else if(temp == 'k') {
printf("enter a starting temperature");
scanf("%f", &kelvin);
fahrenheit=kelvin-273*1.8+32;
celcius=kelvin-273.2;
printf("%f, %f, %f", celcius, fahrenheit, kelvin);
}
}
So it asks for what temperature is being input and the starting temperature but why isn't it calculating the math equation?
It is calculating the math equations
fahrenheit=celcius*9/5+32;
kelvin=celcius+273.15;
but you are not printing it.
Try this
printf("%f, %f, %f", celcius, fahrenheit, kelvin);
And do not forget to change scanf("%s", &temp); to
scanf(" %c", &temp);
temp = tolower(temp); // include <ctype.h> header
or better to place
int c;
while ((c = getchar()) != `\n` && c != EOF);
after scanf(" %c", &temp);. This will eat up all the character other than the first character of the input.
As per OP's comment;
How can I do it so that the Temperature name appears on top of the temperature?
printf("celcius \tfahrenheit \tkelvin);
printf("%5f\t%5f\t%5f", celcius, fahrenheit, kelvin);
Looks like it is calculating, but you're printing the wrong variables. Try replacing c, f, and k with celsius, fahrenheit, and kelvin in the print statement.
You have to be consistent in your variable names, you can't mix them up like you are.
Because you are calculating it like so:
fahrenheit=celcius*9/5+32;
kelvin=celcius+273.15;
However this line is not printing it out, since you have the wrong variables:
printf("%f, %f, %f", c, f, k);
Change that to the proper variable name and type like so:
printf("%f, %f, %f", celcius, fahrenheit, kelvin);
You did not show how you defined your variable temp, but it is extremely dangerous to read a string in this way. If temp is a character, then pointing to the address of it and treating it as a string is asking for trouble. For sure you will have a '\0' written to the location right after temp, and if the user inputs more than a single character the damage they could do is even larger.
You can read a single character with a getc call:
temp = getc(stdin);
I would recommend that you make sure it is lower case - since you are comparing with c:
temp = lower(getc(stdin));
Then obviously, when you print out a variable, you must print out the one you computed. You compute celcius, etc - but your print statement is
printf("%f, %f, %f", c, f, k);
c, f, and k may be valid variables - but they are not the ones you computed in the lines before. Replace the print statement with
printf("Celsius: %.1f; Fahrenheit: %.1f; Kelvin: %.1f\n", celcius, fahrenheit, kelvin);
Or, if you want the name above the number:
printf("\tC\tF\tK\n\t%6.1f\t%6.1f\t%6.1f\n", celcius, fahrenheit, kelvin);
Note the use of \t - the tab character - to get things to align (approximately) and the format specifier %4.1f to say "number in a field width of 6, with one significant digit after the decimal".
One more note - it's Celsius, not celcius. But that is the least of your problems.

Resources