C -- Conditional always jumping to 'Else'? - c

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

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.

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')

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 :-)

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.

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')

Related

How on earth to use char and if statements?

I'm a rookie programmer trying to run a simple code on VS code.
#include<stdio.h>
int main()
{
char* a;
printf("Enter a char");
scanf("%s",&a);
if (a = "yes")
{
printf("Number is 30");
}
else if (a = "no")
{
printf("Number is 50");
}
else{
printf("oops");
}
return 0;
}
I guess looking at the code you guys can figure out what I'm trying to do, if the user enters "yes", a specific sentence need to be displayed and similarly for "no".
The problem here is whatever I write in the input, it will always print the first statement, "Number is 30". I've tried running similar codes but ended up with the same output.
If possible, please explain me how to use char,strings,arrays with if-else statements.
There are several misunderstandings in the posted code.
First there is a misunderstanding of char versus string. A char is for instance a single letter, a single special character like ., ;, etc. (see note1) while a string is a serie of chars. So
'y' is a char
"yes" is a string
You print "Enter a char" but from the code it's obvious that you really want "Enter a string".
This leads to the next problem. To input a string using scanf you need to pass a "pointer to char". Your code pass "a pointer to pointer to char" due to the &. Further the passed pointer must point to some memory. So you need:
char a[10]; // Make it an array of char so that it can hold a string
printf("Enter a string, max 9 characters");
scanf("%9s", a); // No & before a and width specifier used to avoid buffer overflow
Now this part
if (a = "yes")
is not the way to compare two strings in C. For that you need the function strcmp - like:
if (strcmp(a, "yes") == 0)
Putting it together it's like:
int main()
{
char a[10];
printf("Enter a string, max 9 characters");
scanf("%9s", a);
if (strcmp(a, "yes") == 0){
printf("Number is 30");
}
else if (strcmp(a, "no") == 0)
{
printf("Number is 50");
}
else
{
printf("oops");
}
return 0;
}
That said, I don't understand why you print stuff like: "Number is 30" but that's kind of irrelevant here.
note1: The type char is actually an integer type, i.e. a number, but the common use is to map these numbers to characters using ASCII encoding.
There are different ways to initialize a variable to access C string.
char *char_ptr = "Hello";
This initializes char_ptr to point to the first character of the read-only string "Look Here".A C string initialized through a character pointer cannot be modified. When a C string is initialized this way, trying to modify any character pointed to by char_ptr is undefined behaviour. An undefined behaviour means that when a compiler encounters anything that triggers undefined behaviour, it is allowed to do anything it seems appropriate.
A more convenient way to define strings that can be modified is to use:
char str[];
This way you can modify any character in the C string
p.s you also need to use strcmp() for the if statement
You can take string input in C using
scanf(ā€œ%sā€, str);
And to compare the string you need to use:
strcmp(str1, "yes");

How to check if the User entered String is same as that of something

I have this code sample. There is a scanf to hold the input String values from keyboard (i.e Lotus). But even if I type the word Lotus correctly It does not execute the relevant if statement. **Is there any problem with my scanf function???
#include<stdio.h>
int main()
{
char landType,houseType[100],wantToContinue,wantToContinue2;
float installment;
wantToContinue='Y';
while(wantToContinue == 'Y' || wantToContinue == 'y') {
printf("Land Type : ");
scanf(" %c",&landType);
if(landType == 'A') {
printf("Type of House: ");
scanf(" %s", houseType);
if(houseType == "Lotus") {
//this won't go inside if statement even if I type Lotus correctly
installment=4000000-500000;
printf("Monthly Installment : R.s %.2f\n",installment/120);
printf("Do you want to Continue?(Y/y or N/n) : ");
scanf(" %c",&wantToContinue2);
if(wantToContinue2 == 'Y' || wantToContinue2 == 'y') {
wantToContinue=wantToContinue2;
printf("\n");
}else{
wantToContinue='N';
}
}
}
}
}
Be careful when comparing two strings in C. You should use the strcmp function from the string.h library, like so:
if(strcmp("Lotus", houseType) == 0)
When you write if(houseType=="Lotus") you are actually comparing the base address of the two strings and not their actual content.
In C, strings cannot be compared using ==. This is because strings are not a basic data type in C, that is C does not inherently understand how to compare them - you must use a function instead.
A standard function for comparing strings in C is strcmp(), e.g.:
if (strcmp(houseType, "Lotus") == 0)
{
// do some work if the strings are equal
}
To explain further, your initial attempt to compare strings using housetype == "Lotus" actually compares the address where the first character of the character array houseType is stored with the address where the first character of the character array "Lotus" is stored.
This happens because strings in C are just arrays of characters - they are not an inherent data type, C does not, as such, understand the difference between an array of integers and an array of characters, they are all just numbers arranged contiguously somewhere in memory and it treats them as such unless you specifically use code that operates on them as strings instead.

C Programming - Trouble with pointers, no console output

After getting moderately comfortable with Java, i'm now trying to expand my horizon and try my hand at C programming. However, I cannot seem to wrap my head around the pointers in C, even with having visited multiple videos and websites.
The code below is supposed to take in two strings from the user, get the length of both of them and then compare the lengths against one another. The program should then return the longest of the two names (taking great care to return the length until newline, not the allocated size for the variable) by means of a pointer. So, when the user inputs 'Peterson'(name1) and 'Thisisareallylonglastname'(name2) the program should return 'Thisisareallylonglastname' by means of the pointer / name2 connection.
The problem I am having is that when trying to run the code (written in the Eclipse Neon C/C++ IDE, using the MinGW compiler) I get no output in the console. I am fairly certain I have set the path to my MinGW install correctly in windows, but to be sure I have also added the enviroment manually to the project. Between my confusion for pointers and generally being a crappy coder I am not sure what the (undoubtedly novice) mistake with my program is. I am not getting errors of any kind in the Neon IDE.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
/* Two variables that take family names' input from the user with a maximum length of 256 */
char name1[256];
char name2[256];
char *ch = NULL;
printf("When two people marry there can sometimes be a debate which last/family name will henceforth be used (as a hyphenated last name is not always feasible.");
printf("A simple way to avoid squabbles is to simply take the longest family name of the two (soon-to-be) partners.");
printf("This program will take your name inputs and compare their length against one another; it will then return the longest name to be put on the document.");
printf("Enter your last name for 1 :");
gets(name1);
printf("Enter your last name for 2 :");
gets(name2);
int size1 = strlen(name1);
printf("Length of name 1:");
printf(size1);
int size2 = strlen(name2);
printf("Length of name 2:");
printf(size2);
if (size1 > size2)
{
ch = &name1;
}
else
{
ch = &name2;
}
if(!ch)
{
printf("The largest family name found is:");
printf(*ch);
}
return(0);
}
One major problem is that your final output is under the condition if (!ch) - which, in English, reads "if the pointer ch is null-valued". Since it points to one of two (non-null) memory locations, this check will never pass.
If you change that to if (ch) (or just omit the check, since we know it's not null) and fix the printf problems pointed out by others in the comments, I think you'll get better results.
A pointer to char and an array of char are both ways of representing strings in C and as such are the same type. The main difference being that with the array the memory is allocated at compile time and with a pointer you either assign an array to it (like you're trying to do) or dynamically allocate the memory.
So when you're doing
ch = &name1;
What you're actually doing is trying to assign a pointer to the string name1 to ch, which isn't the same type and should throw up an error. Instead you really want to be doing
ch = name1;
Conversely, *ch is the same as ch[0] - you're accessing the first character of the string so to print it out you want to have
printf("%s",ch);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
/* Two variables that take family names' input from the user with a maximum length of 256 */
char name1[256];
char name2[256];
char *ch = NULL;
printf("When two people marry there can sometimes be a debate which last/family name will henceforth be used (as a hyphenated last name is not always feasible.");
printf("A simple way to avoid squabbles is to simply take the longest family name of the two (soon-to-be) partners.");
printf("This program will take your name inputs and compare their length against one another; it will then return the longest name to be put on the document.");
printf("Enter your last name for 1 :");
gets(name1);
printf("Enter your last name for 2 :");
gets(name2);
int size1 = strlen(name1);
printf("Length of name 1: %d", size1);
int size2 = strlen(name2);
printf("Length of name 2: %d", size2);
if (size1 > size2)
{
ch = name1;
}
else
{
ch = name2;
}
printf("The largest family name found is: %s", ch);
return(0);
}
This should do the trick. You should also use scanf("%s", str) instead of gets.
When you do char name1[256] name1 is "considered an pointer", so you must do ch = name1 not ch = &name1, because both ch and name1 are pointers.
when you did:
if(!ch)
{
printf...
}
you will only print if the ch is null, wich you don't want, because, in this case, you want to print if ch has a value so you should do:
if(ch)
{
printf...
}
also in c printf must receive the information about the variable you are trying to print, check printf examples to understand it
The main problem is that you're expecting printf to act as a polymorphic function like System.out.println, and it doesn't. The prototype for printf is
int printf( const char * restrict format, ... );
The first argument is always a character string; the string may contain conversion specifiers that control how any additional arguments are formatted.
So instead of writing:
printf("Length of name 1:");
printf(size1);
you'd write:
printf( "Length of name 1: %d\n", size1 );
or
printf( "Length of name 1: " );
printf( "%d\n", size1 );
The %d in the format string tells printf that the corresponding argument should have type int, and that you want to display its value as a string of decimal digits. See the online C 2011 standard, section 7.21.6.1, for the complete list of conversion specifiers.
printf doesn't automatically append a newline to all output the way System.out.println does - you have to specify it in the format string (\n).
Standard output is typically line buffered - output won't show up on the console until a) the buffer is full, b) the buffer is manually flushed with fflush, c) a newline appears in the buffer, or d) an input function (fgets, scanf, etc.) immediately follows the output function.
Array semantics in C and Java are wildly different. In C, arrays are not reference objects - they don't point to dynamically-allocated memory on the heap. However, the array subscript operation a[i] is defined in terms of pointer arithmetic - *(a + i). What happens in C is that when an array expression is not the operand of the sizeof or unary & operators, or isn't a string literal used to initialize an array in a declaration, the expression is converted ("decays") from type "N-element array of T" to "pointer to T", and the value of the expression is the address of the first element of the array.
This is a very long-winded way of saying that instead of writing
ch = &name1;
you should be writing
ch = name1;
instead. The expression name1 "decays" to a pointer to the first element of the array, and the resulting type of the expression is char *. The type of the expression &name1 is char (*)[256] (pointer to 256-element array of char), which is not what you want. They'll both evaluate to the same location (modulo any type conversions), but type matters.
Finally...
NEVER NEVER NEVER NEVER NEVER use gets. It will introduce a point of failure / major security hole in your code. It was deprecrated shortly after the release of the C99 standard, and has been officially removed from the standard library in C2011. That one library function has been responsible for untold amounts of mayhem over the decades. Do not use it, not even in toy code. It is the "Highlander II" of the C programming language - it never existed. Use fgets instead.

scan arithmetic operands c and compare them with string

I am trying to scanf arithmetical operands into variable. I want to put "+" into variable. I tried everything I have found but nothing has worked so far. The best thing I came with is:
char plus = "+";
char* c;
scanf("%c", &c);
if (strcmp(plus, c) == 0) {
printf("you have + in variable");
But this does not work. It seems like "+" does not get into variable plus nor does it get scanned into variable using scanf. Is there any trick for this?
There are multiple errors in there:
you declare a char plus and you initialize it with a char* (and not a char).
scanf with %c expects a char* but you are providing a char**
you are comparing a char with a char* in strcmp
If you are dealing with single character operators there's no need to do things more complex than they are:
char plus = '+';
char c;
scanf("%c",&c);
if(plus == c)
printf("you have + in variable");

C code not working properly

I'm just learning how to code in C, It's my first non-web language and it's not off to a good start.
I have the following code:
//
// main.c
// Greeting
//
// Created by Austen on 2013-06-27.
// Copyright (c) 2013 Austen. All rights reserved.
//
#include <stdio.h>
int main()
{
int confirm[100];
char name[100];
char mood[100];
printf( "Please enter your name: " );
scanf("%s", name);
printf( "Hey there, %s . How are you? ", name);
scanf("%s", mood);
printf("Oh, you are %s?. Enter 1 or 0: ", mood);
scanf("%i", confirm);
if (confirm == 1) {
printf("Oh good!");
}
else {
printf("Make up your mind");
}
getchar();
return(0);
}
For some reason I just can't get it to work, I've had to change a few things in order for Xcode to stop moaning at me for so many reasons.
It's giving me a
warning: Comparison between pointer and integer int* and int
When I run it, even if I enter 1, it tells me to make up my mind.
Any help would be great, just so I know better next time. It's probably something really simple.
No need to create an array to hold an answer for confirm, a normal int will do:
int confirm;
But as scanf expects a pointer you need to pass its address like so:
scanf("%d", &confirm);
Finally, this - scanf("%i", confirm); should actually be this - scanf("%d", &confirm);.
%d is the standard formatting character for integer variables.
After that, everything compiled fine.
C is always pass by value, so there's no way for scanf to store the value you enter in the variable provided, unless it reaches inside memory where it resides and writes it to memory directly.
That's why it asks for the memory address of the variable, rather than the variable itself (you provide the address of something by prepending & to it).
Arrays are already treated as addresses (pointers to be more precise and pointers store the address of something) when passed as arguments to a function which is why you don't do it for them.
Some information on pointers and arrays here.
The reason you get that warning is because you're comparing an array of 100 integers to 1 integer. The correct code would be something like this
if (confirm[0] == 1)
or even easier
int confirm;
scanf("%d", &confirm);
if (confirm == 1)
Use %d for integers (for confirm)
Confirm is declared as an array, but you just want a plain integer. Remove the [100] after confirm in the declaration. It should just be;
int confirm;
The warning you got was because confirm was an array and it tried to compare the array's base address(confirm) to an integer value (1).
Whenever you declare an array, the base address of that array is available in the array name.(Eg. confirm here)
Replace the scanf line which takes confirm with
scanf("%d",&confirm);
it should work fine then

Resources