`else if` condition not properly working in my program in c - c

I am new and I don't know to to resolve this error.
When I give inputs for the third else if statement condition it gives the output as salary =0.
Can anyone explain why this happening?
I want to get the answer as :the salary of the candidate = 7000
but the output shows as : the salary of the candidate = 0
/******************* calculating the salary *********************/
/***** bitwise operator ***********/
#include <stdio.h>
int main()
{
char gen;
int qual, y_o_s, sal = 0 ;
printf ( "Enter Gender, Years of Service and Qualifications ( 0 = G, 1 = PG ):\n" );
printf("enter the gen, y_o_s, qual, \n");
scanf("%c\n%d\n%d", &gen, &y_o_s, &qual);
if (gen == 'M' && y_o_s >= 10 && qual == 1)
sal = 15000;
else if ((gen == 'M' && y_o_s >= 10 && qual == 0) ||
(gen = 'M' && y_o_s < 10 && qual == 1))
sal = 10000;
else if (gen == 'M' && y_o_s < 10 && qual == 0)
sal = 7000;
else if (gen == 'F' && y_o_s >= 10 && qual == 1)
sal= 12000;
else if (gen == 'F' && y_o_s >= 10 && qual == 0)
sal = 9000;
else if (gen == 'F' && y_o_s < 10 && qual == 1)
sal = 10000;
else if (gen == 'F' && y_o_s >= 10 && qual == 0)
sal = 6000;
printf("the salary of the candidat = %d\n", sal);
return 0;
}
I want to get the answer as :the salary of the candidate = 7000
but the output shows as : the salary of the candidate = 0.

Alter your if-else-if ladder like :
#define POST_GRAD 1
#define SEX_MALE 'M'
if (SEX_MALE == gen) {
if (POST_GRAD == qual) {
sal = (y_o_s >= 10) ? 15000 : 10000;
} else { // undergrad
sal = (y_o_s >= 10) ? 10000 : 7000;
}
} else { // not Male
if (POST_GRAD == qual) {
sal = (y_o_s >= 10) ? 12000 : 10000;
} else { // undergrad
sal = (y_o_s >= 10) ? 9000 : 6000;
}
}
It's easier to follow. Notice, that constants like POST_GRAD are on the left side comparator ==, it helps compiler catch unintended typos like = for comparisons.
Also, you may want those salaries at one place like :
#define MALE_PG_EXP_SAL 15000
#define MALE_UG_EXP_SAL 10000
// and so on
#define FEMALE_UG_EXP_SAL 9000
#define FEMALE_UG_INEXP_SAL 6000
When they change, you can find them at one place to modify.
PS: I wouldn't want to work at this place.

You are assigning a value to gen
else if ((gen == 'M' && y_o_s >= 10 && qual == 0) ||
(gen = 'M' && y_o_s < 10 && qual == 1))
^
So when you get to your next line gen is no longer what you expect.
else if (gen == 'M' && y_o_s < 10 && qual == 0)
^^
And then improve the code with SparKots suggestions.

Related

How to make conditional statements more compact in C?

I have a code snippet that uses if-else if-else block. I am wondering any potential ways to shorten the lengthy conditional statement else if (cardLength == 16) && (numberArray[0] == 5 && (numberArray[1] == 1 || numberArray[1] == 2 || numberArray[1] == 3 || numberArray[1] == 4 || numberArray[1] == 5)), for instance, without changing the logic. In python, I can do in this way: if (cardLength == 16) and (numberArray[0:2] in range(51,56)). Are there any specific syntax sugar that I can use fo this purpose in C?
if (cardLength == 15) &&
(numberArray[0] == 3 && (numberArray[1] == 4 || numberArray[1] == 7))
{
printf("AMEX\n");
}
else if (cardLength == 16) &&
(numberArray[0] == 5 && (numberArray[1] == 1 || numberArray[1] == 2 || numberArray[1] == 3 || numberArray[1] == 4 || numberArray[1] == 5))
{
printf("MASTERCARD\n");
}
else if (cardLength == 13) && (numberArray[0] == 4)
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
Put it into a (static) function. Dont think about performance/optimisation yet.
static char *card_leng_type2string( unsigned len, int *arr)
{
if (len == 15 && arr[0] == 3 && arr[1] == 4 ) return "AMEX";
if (len == 15 && arr[0] == 3 && arr[1] == 7 ) return "AMEX";
if (len == 16 && arr[0] == 5 && arr[1] == 1 ) return "MASTERCARD";
if (len == 16 && arr[0] == 5 && arr[1] == 2 ) return "MASTERCARD";
if (len == 16 && arr[0] == 5 && arr[1] == 3 ) return "MASTERCARD";
if (len == 16 && arr[0] == 5 && arr[1] == 4 ) return "MASTERCARD";
if (len == 16 && arr[0] == 5 && arr[1] == 5 ) return "MASTERCARD";
if (len == 13 && arr[0] == 4) return "VISA";
return "INVALID";
}
Now your calling code could just do:
printf("%s\n", card_leng_type2string(cardLength, numberArray) );
You could convert the first two digits of the numberArray into a new number like this
num = numberArray[0]*10 + numberArray[1]
and then use that into the conditional statements to make them more readable
int num = numberArray[0]*10 + numberArray[1]
if ((cardLength == 15) && ((num == 37) || (num == 34)))
{
printf("AMEX\n");
}
else if ((cardLength == 16) && ((num >= 51) && (num <= 55)))
{
printf("MASTERCARD\n");
}
else if ((cardLength == 13) && ((num >= 40) && (num <= 49)))
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
return 0;
}
Assuming that entries in numberArray are in range 0-9, you could use strchr function. This returns non-NULL if a given string contains a specific character.
Replace:
numberArray[1] == 4 || numberArray[1] == 7 || numberArray[1] == 9
with
strchr("479", '0' + numberArray[1])
If numberArray was an array of character then the check could be simplified to strchr("479", numberArray[1])
If you want the logic intact and only want modification for readbility, you could try adding a preprocessor directive gloabally.
This would replace the text or inline function anywhere you use it in the program.
Example
#define AMEX_CONDITION (cardLength == 15) && (numberArray[0] == 3 && (numberArray[1] == 4 || numberArray[1] == 7))
and use it in your if as
if(AMEX_CONDITION){
printf("AMEX");
}

How can I fix the If and structure problem in C?

My program should ask user for last full moon date, check if data is correct and then ask user does he want to see dates of next or previouse full moons and how many. I have some problems with "if"and "else if". I don't know why but program basiclly acts like it doesn't see that user gave anything in this line scanf_s("%s", &czy_kolejne); and goes straight to else{printf("\nBłędny znak."); }. I'm also not sure if structure for date is the best way to do it, becasue it have some problem with previouse dates. Could someone give me any advice ?
#include<time.h>
#include<stdlib.h>
int main()
{
int rok, miesiac, dzien;
char czy_kolejne;
int kolejne_pelnie;
int poprzednie_pelnie;
printf_s("Kiedy byla ostatnia pelnia ? (DD.MM.YYYY): ");
scanf_s("%d.%d.%d", &dzien, &miesiac, &rok);
if (rok >= 0)
{
if (miesiac >= 1 && miesiac <= 12)
{
if ((dzien >= 1 && dzien <= 31) && (miesiac == 1 || miesiac == 3 || miesiac == 5 || miesiac == 7 || miesiac == 8))
{
printf_s("Poprawna data. %d.%02d.%d", dzien, miesiac, rok);
}
else if ((dzien >= 1 && dzien <= 31) && (miesiac == 10 || miesiac == 12))
{
printf_s("Poprawna data. %d.%d.%d", dzien, miesiac, rok);
}
else if ((dzien >= 1 && dzien <= 30) && (miesiac == 4 || miesiac == 6 || miesiac == 9))
{
printf_s("Poprawna data. %d.%02d.%d", dzien, miesiac, rok);
}
else if ((dzien >= 1 && dzien <= 30) && miesiac == 11)
{
printf_s("Poprawna data. %d.%d.%d", dzien, miesiac, rok);
}
else if ((dzien >= 1 && dzien <= 28) && miesiac == 2)
{
printf_s("Poprawna data. %d.%02d.%d", dzien, miesiac, rok);
}
else if (dzien == 29 && miesiac == 2 && (rok % 400 == 0 || (rok % 4 == 0 && rok % 100 != 0)))
{
printf_s("Poprawna data. %d.%02d.%d", dzien, miesiac, rok);
}
else
{
printf_s("Liczba dni w miesiacu jest bledna.");
}
}
else
{
printf_s("Nie ma tylu miesiecy.");
}
}
struct tm t = { 0 };
t.tm_mday = dzien;
t.tm_mon = miesiac - 1;
t.tm_year = rok - 1900;
int skip = 29;
t.tm_mday += skip;
mktime(&t);
char buffer[30];
printf("\nCzy wyliczyc daty kolejnych pelni ? (T/N)");
scanf_s("%s", &czy_kolejne); //The problem starts right here.//
if ((czy_kolejne=='t') || (czy_kolejne=='T'))
{
printf_s("\nIle dat w przod?");
scanf_s("%d", &kolejne_pelnie);
for (int i = 1; i <= kolejne_pelnie; i++)
{
int skip = 29 * i;
t.tm_mday += skip;
strftime(buffer, 30, "\n%d-%m-%Y", &t);
puts(buffer);
}
}
else if ((czy_kolejne=='n') || (czy_kolejne=='N'))
{
printf_s("\nIle dat w tył wyliczyc?");
scanf_s("%d", &poprzednie_pelnie);
for (int i= 1; i <= poprzednie_pelnie; i++)
{
int skip = 29 * i;
t.tm_mday -= skip;
strftime(buffer, 30, "\n%d.%m.%Y", &t);
puts(buffer);
}
}
else
{
printf("\nBłędny znak.");
}
return 0;
}
At least two things are wrong with scanf_s("%s", &czy_kolejne), when czy_kolejne is of datatype char:
First, %s will read in a 0-terminated string, but you provide a buffer of type char; this is undefined behaviour, very likely just corrupting memory and leading to weird results. For reading in exactly one character use format "%c".
Second, if you make czy_kolejne to a char array, e.g. char czy_kolejne[10], then scanf_s with a format %sis OK, but it requires an additional argument indicating the buffer size. I.e. you'd have to write scanf_s("%s", &czy_kolejne, sizeof(czy_kolejne)).

C Operator priority at CLA certification exam

Currently, I'm taking C language certification course at cppinstitute.org.
In one of it's quizzes there is a question as below to recognize output.
int i = 1,j= 1;
int w1,w2;
w1 = (i>0) && (j<0) || (i<0) &&(j>0);
w2 = (i<=0) || (j>=0) && (i>=0) || (j<=0);
printf("%d",w1 == w2);
I think the program should print 0 to the screen, but the quiz accepts printing 1 as the answer.
Am I correct?if not ,where I'm wrong?
Thanks in advance!I'm a beginner.
Here, && higher precedence than || operator.
So,
w1 = (i>0) && (j<0) || (i<0) &&(j>0);
= 1 && 0 || 0 && 1;
= 0 || 0
= 0
And
w2 = (i<=0) || (j>=0) && (i>=0) || (j<=0);
= 0 || 1 && 1 || 0
= 0 || 1 || 0
= 1 || 0
= 1
So, w1 == w2 become false. So, correct output is 0.

If else statement troubles in C

I am trying to input a seat number of "15" into this function and get the char value of 'A'. However, for some reason every time I input a number that should be a type 'A'(because its remainder doesn't equal any of the aforementioned values) it gets stuck in the 'M' else if statement. I really do not understand why and would like some help if you have time :)
char whatTypeOfSeat(int seatNumber){
if((seatNumber % 6) == 0 || seatNumber % 6 == 1 || seatNumber == 1) {
typeOfSeat = 'W';
}
else if((seatNumber % 6) == 2 || (seatNumber % 6) == 5|| seatNumber == 5,2 ) {
typeOfSeat = 'M';
}
else {
typeOfSeat = 'A';
}
return typeOfSeat;
}
This does not do what you think it does:
seatNumber == 5,2
If you want to check against both values, you need separate conditionals
else if((seatNumber % 6) == 2 || (seatNumber % 6) == 5|| seatNumber == 5 || seatNumber == 2 ) {

How to pack three unsigned integers into an unsigned short in C

I have an assignment from college, in which I have to use C to pack three unsigned integers representing a date (the year must be between 1970 and 2097) and compress it into an unsigned short, then unpack it again and show it in command line.
Can someone help me please?
Below I leave the code I have so far (declared variables outside functions and function signatures cannot be changed)
Edit: I have a second problem, which is the getchar function not return anything, setting the three date fields to 0...
#include <stdio.h>
typedef unsigned short pkdate_t;
typedef struct date3 {
unsigned year;
unsigned month;
unsigned day;
} date3_t;
int ror (int val, unsigned n) {
return (val >> n)|(n << (32 - n));
}
int pack_date (pkdate_t * dst, date3_t * src) {
if ((*src).year < 1097 || (*src).year > 2097 || (*src).month < 1 || (*src).month > 12 || (*src).day < 1 ||
((*src).month == 2 && (((*src).year / 4 == 0 && (*src).day > 29) || ((*src).year / 4 != 0 && (*src).day > 28))) ||
(((*src).month == 2 || (*src).month == 4 || (*src).month == 6 || (*src).month == 9 || (*src).month == 11) && (*src).day == 31)) return -1;
//(*dst) = (*src).year * 10 + (*src).month + (*src).day; "wrong code"
return 0;
}
int unpack_date (date3_t * dst, pkdate_t date) {
(*dst).year = date % 10000;
date = date / 10000;
(*dst).month = date % 100;
date = date / 100;
(*dst).day = date % 100;
if ((*dst).year < 1097 || (*dst).year > 2097 || (*dst).month < 1 || (*dst).month > 12 || (*dst).day < 1 ||
((*dst).month == 2 && (((*dst).year / 4 == 0 && (*dst).day > 29) || ((*dst).year / 4 != 0 && (*dst).day > 28))) ||
(((*dst).month == 2 || (*dst).month == 4 || (*dst).month == 6 || (*dst).month == 9 || (*dst).month == 11) && (*dst).day == 31)) return -1;
else return 0;
}
int main () {
int k = ror(30, 2);
printf("%s\n", "exercicio 1:");
printf("%d turned into %d\n", 30, k);
pkdate_t date = 0;
date3_t newDate;
newDate.year = 2000;
newDate.month = 04;
newDate.day = 02;
printf("%s\n", "exercicio 2:");
//printf("%s\n", "insira uma data (yyyymmdd) e de seguida pressione enter:");
//int i = 1000;
//while (i > 0) {
//newDate.year += getchar() * i;
//i = i / 10;
//}
//i = 10;
//while (i > 0) {
//newDate.month += getchar() * i;
//i = i / 10;
//}
//i = 10;
//while (i > 0) {
//newDate.day += getchar() * i;
//i = i / 10;
//}
//"the commented part above does not get any values from command line, still figuring that part out :)"
pack_date(&date, &newDate);
printf("packed date: %hu\n", date);
unpack_date(&newDate, date);
printf("unpacked date: %u/%u/%u\n", newDate.year, newDate.month, newDate.day);
//newDate.year = 2000;
//newDate.month = 12;
//newDate.day = 14;
//pack_date(&date, &newDate);
//printf("%s\n", "exercicio 3:");
//printf("date is %hu\n", date);
// "ignore"
return 0;
}
In C, there aren't so much use cases that qualify for bitfields, but this one is a perfect fit IMHO since it saves you a lot of headaches from bit shifting:
struct date_struct
{
unsigned short year:7;
unsigned short month:4;
unsigned short day:5;
};
union date
{
struct date_struct bits;
short date;
}
First, you should think about how the date should be presented inside this unsigned short.
End even firster, you should be aware that the length of a(n unsigned) short is not defined exactly, only its minimum, which is 16 bits.
So let's try to pack such a date into 16 bits.
As already was commented as I write this answer, you can shrink the years into a range of y-1970 = 0..127, which makes you need 7 bits. The months need 4 bits and the days 5, in total 16 bits.
Now think about how you determine the single parts and how you shift them so that they fit.

Resources