How to make conditional statements more compact in C? - 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");
}

Related

Laravel Check All Multiple Requests Boolean Variable's value to True

I made an if condition for checking request boolean in laravel controller method update, it worked but the line seems too long and i want make the code in short line. And this is my code that i wrote:
if( $request->jamlak == 1
&& $request->kontrak == 1
&& $request->jamuk == 1
&& $request->sprin_pc == 1
&& $request->pc == 1
&& $request->izin_bekal == 1
&& $request->sprin_komisi == 1
&& $request->bek == 1
&& $request->komisi == 1
&& $request->bagudang== 1
&& $request->pem_gudang == 1
&& $request->bast == 1
&& $request->lpp == 1
&& $request->pemerataan == 1){
$validatedData['is_complete'] = 1;
}
else {
$validatedData['is_complete'] = 0;
}
Task::where('id', $task->id)
->update($validatedData);
return redirect('/admin/tasks')->with('success', 'New post has been updated!');
So about this code i want to make $validatedData['is_complete'] turns to be 1(true) after it checks all of requests 1 True, Is there any chance to make it way more efficient line?

`else if` condition not properly working in my program in 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.

How to make sure that the randomized coordinates will not fall into specific coordinates in a 2D array? The language is C

I am creating a game in C, and I want to randomly place blocks and foods inside a 2d array. I have randomized the x and y coordinates of the blocks and the food into 1d arrays, i.e. foodCol[] and foodRow[]; blockCol[] and blockRow[]. However, there comes a possibility that the blocks and foods would fall into the same coordinates. I also want them not to to be placed on the coordinate (1, 1) and beside each other, except diagonally. I came up with this code, but it does not work and maybe there are other intuitive approach.
Here is the code:
for (foodCount = 0; foodCount < randDim; foodCount++){
for (foodCount2 = 0; foodCount2 < randDim; foodCount2++){
while ((foodCol[foodCount] == blockCol[foodCount2] && foodRow[foodCount] == blockRow[foodCount2]) ||
(foodCol[foodCount] == blockCol[foodCount2]+1 && foodRow[foodCount] == blockRow[foodCount2]) ||
(foodCol[foodCount] == blockCol[foodCount2]-1 && foodRow[foodCount] == blockRow[foodCount2]) ||
(foodCol[foodCount] == blockCol[foodCount2] && foodRow[foodCount] == blockRow[foodCount2]+1) ||
(foodCol[foodCount] == blockCol[foodCount2] && foodRow[foodCount] == blockRow[foodCount2]-1) ||
(foodRow[foodCount] == 1 && foodCol[foodCount] == 1) ||
(foodRow[foodCount] == 2 && foodCol[foodCount] == 1) ||
(foodRow[foodCount] == 1 && foodCol[foodCount] == 2) ||
(foodRow[foodCount] == 2 && foodCol[foodCount] == 2)){
foodNum2 = (rand()%9)+1;
shuffle(&foodCol[foodCount2], &foodCol[foodNum2]);
shuffle(&foodRow[foodCount2], &foodRow[foodNum2]);
}
}
}
Remarks: the shuffle function is just a basic function of shuffling 1d arrays. Also, the foodcount and randdim are irrelevant to my problem.
Thanks!

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

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

Resources