3

I am working on learning C and am using some practice problems from the Python book I recently finished. My C book is in the mail, but I wanted to get a head start. I was putting together a simple temperature conversion program and for some reason it always jumps to the 'Else' clause in my conditional... I'm sure I'm missing something simple, but I can't seem to figure it out. Any ideas?:

#include<stdio.h>

main()
{
float temp_c, temp_f;
char convert_from[1];

printf("Convert from (c or f): ");
scanf("%c", &convert_from);

if(convert_from == "c")
{
    printf("Enter temperature in Celsius: ");
    scanf("%f", &temp_c);

    temp_f=(1.8*temp_c)+32;

    printf("The temperature in Fahreinheit is: %f \n", temp_f);
}

else if(convert_from == "f")
{
    printf("Enter temperature in Fahreinheit: ");
    scanf("%f", &temp_f);

    temp_c=(temp_f/1.8)-32;

    printf("The temperature in Celsius is: %f \n", temp_c);
}

else
    printf("Invalid choice. \n");

}
cgc
  • 98
  • 5

5 Answers5

7

If you are comparing characters do this:

char convert_from; 

printf("Convert from (c or f): "); 
scanf("%c", &convert_from); 

if (convert_from == 'c') 
{ 

Otherwise you can't perform the comparison with a string literal "c" (note the double quotes) like that.

Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
  • 1
    For more explanation on what's going in in the original code... Strings aren't quite as simple as in other languages. When you do (convert_from == "c") in the original problem statement, that's creating a new 'string' with only 'c' in it, checking to see if it's exactly the *same string* as convert_from (which it's not, because it's a *new* string), and always coming up false. You could use the strings instead, but then you'd need strcmp(convert_from, "c") - which will return 0 if the strings are equal. – Rophuine Feb 10 '12 at 23:35
  • You shouldn't use what I've suggested - it opens up another can of bugs - I just wanted to explain why it wasn't working. – Rophuine Feb 10 '12 at 23:40
2

In the expression:

if (convert_from == "c")

convert_from array is converted to a pointer to char, so you are basically comparing a pointer to char to another pointer to char. "c" is a string literal while 'c' is a char (note the use of "" in the first case and of '' in the second case).

With a char convert_from[1]; declaration, here would be the correct code:

char convert_from[1];
scanf("%c", convert_from);
if (convert_from[0] == 'c')

but it is more natural to directly use a char instead of an array 1 of char:

char convert_from;
scanf("%c", &convert_from);
if (convert_from == 'c')
ouah
  • 142,963
  • 15
  • 272
  • 331
1

Well two problems here.

First: You want only to read a single character, so declaring

char convert_from;

instead of an array of chars with size 1 (as char convert_from[1] did).

And secondly you need to actually compare to a single character, so you would need to do

if (convert_from == 'c') ...

instead of "c", because "foo" is a string in C which in turn is a pointer to a constant character array (const char *).

Additionally: which compiler did you use? Mine (llvm-gcc 4.2) warned me about the issues. So either your compiler is quite bogus or you will urgently have to pay attention to compiler warnings. This might be difficult, as warnings are no errors, however, warnings are there for a reason :-)

cli_hlt
  • 7,072
  • 2
  • 26
  • 22
  • gcc (Debian 4.4.5-8) 4.4.5 -- I wonder why I didn't get those warnings... It compiled without error and ran, but jumped to the final else statement every time? It's working now though, and I understand why after the explanations. Thanks everyone! – cgc Feb 10 '12 at 23:45
  • My compiler says: test.c: In function ‘main’: test.c:27: warning: format ‘%c’ expects type ‘char *’, but argument 2 has type ‘char (*)[1]’ test.c:27: warning: format ‘%c’ expects type ‘char *’, but argument 2 has type ‘char (*)[1]’ -- anyway, good that you got it now :) have fun learning more ;) – cli_hlt Feb 10 '12 at 23:49
1

In C, you cannot compare strings using == (what happens if you do is that the memory locations of the strings get compared, which will yield different results in most cases).

Also scanf("%c", &convert_from); is wrong. The array itself will already decay into a pointer, so scanf("%c", convert_form); will suffice. In this case however, convert_form will not contain something your C library will consider a string (strings are null-terminated in C). A minimally invasive change for getting your code to work would be changing

if (convert_from == "f") [...]

to

if (covert_form[0] == 'f') [...]

(mind the '' instead of the "", which is a character literal, which basically is just a number and can thus be compared using ==).

A more idiomatic way to do this would be to declare convert_form as char convert_form and then use scanf("%c", &convert_form);, which would accomplish the same as the above.

fnl
  • 2,209
  • 19
  • 17
0

First of all since you are reading only one character at a time define it as

char convert_from;

next it is not advisable to compare strings directly hence the statement should be

if(convert_from == 'c')
Manas Shah
  • 19
  • 5