Proper way to declare a "not set" enum value - c

If using an enum for which you cannot alter the contents, e.g.,
typedef enum {
sun=0,
mon=1,
tue=2,
wed=3,
thu=4,
fri=5,
sat=6,
} days;
Is there any way to safely have some code that looks like:
days day;
day = /*what goes here*/;
if (somecondition)
{
day = sun;
}
else if (othercondition)
{
day = mon;
}
if (day != /*what goes here*/)
{
use(day);
}
Besides creating another sentinel that shows that day was set and without relying on knowing the contents of the days enum?

In similar coding, I try to reserve the first enum (0) as the "NULL" value:
typedef enum {
nullday = 0,
sun=1,
mon=2,
tue=3,
wed=4,
thu=5,
fri=6,
sat=7,
} days;
That allows for a 'non-day' day:
days day;
day = nullday;
if (somecondition)
{
day = sun;
}
else if (othercondition)
{
day = mon;
}
if (day != nullday)
{
use(day);
}
Another version of the code:
typedef enum {nullday=0, sun, mon,tue,wed,thu,fri,sat} days;
...
days day = nullday;
if (somecondition)
{
day = sun;
}
else if (othercondition)
{
day = mon;
}
if (day)
{
use(day);
}

Related

Military time and standard time logic works but time indicator string is not working

The goal of my code was to be able to switch between standard and military time if there was a tag when executing it.
When in military time, it has to have "24" at the end, and when in standard it has to have "am" or "pm" at the end.
It seems I am able to get the ampm logic, but it shows 24 and not am or pm - only 24. Is there something wrong with the modestring in my bigger else block?
void show(struct tm *dateinfo, int ampm)
{
char timestring[9];
char modestring[3];
int hour;
hour = dateinfo->tm_hour;
if ( ampm == 0 )
{
sprintf(timestring,
"%02d:%02d:%02d",
hour,
dateinfo->tm_min,
dateinfo->tm_sec);
sprintf(modestring, "24");
}
else
{
if ( hour < 12 )
{
if ( hour == 0 )
{
hour = 12;
}
sprintf(modestring, "am");
}
else
{
if ( hour == 12 )
{
hour = 12;
}
else
{
hour = hour % 12;
}
sprintf(modestring, "pm");
}
}
printf("\r%s %s", timestring, modestring);
fflush(stdout);
}
You're only setting timestring in the if ( ampm == 0 ) block. Move it to after the if block after setting hour.
if ( ampm == 0 )
{
sprintf(modestring, "24");
}
else if ( hour < 12 )
{
if ( hour == 0 )
{
hour = 12;
}
sprintf(modestring, "am");
}
else
{
if ( hour > 12 )
{
hour = hour % 12;
}
sprintf(modestring, "pm");
}
sprintf(timestring,
"%02d:%02d:%02d",
hour,
dateinfo->tm_min,
dateinfo->tm_sec);

How to include the size of array into the for loop without triggering error

This is the login function that I want to implement.
The problem is that I want to use the syntax of sizeof(id) in the for loop without triggering error.
Any solution??
int login();
int login()
{
int i, att, num_i, status;
att = 1;
status = 0;
num_i = 999;
char* id[100], * pass[100];
char* inp_id[100], inp_pass[100];
id[0] = "id1"; ///Sample ID
id[1] = "id2";
id[2] = "id3";
pass[0] = "pass1"; ///Sample pass
pass[1] = "pass2";
pass[2] = "pass3";
while (att <= 3)
{
printf("ID:");
scanf("%s", &inp_id);
for (i = 0; i < 3; ++i) /// I wanted this to repeat accordingly to the size of ID that was stored
{
if (strcmp(inp_id, id[i]) == 0) /// Cuz when I declare i > 100 when it call for i[4] and it doesn't exist, error occured.
{
num_i = i;
break; /// wanted it to break out of the loop once it got the id that's similar to what was entered
}
}
printf("Password:");
scanf("%s", &inp_pass);
if (num_i < 100)
{
if (strcmp(inp_pass, pass[num_i]) == 0)///checking pass according to the positon of i on the ID
{
status = 1;
att = 999;
}
}
att++;
}
I've deleted a portion of the code due to it asking for more information.
A simplified example of what I described in my comment:
Or at least these are components to help you understand.
struct account {
char *id;
char *pass;
};
static const struct account account_list[] = {
{ .id = "id1", .pass = "pass1" },
{ .id = "id2", .pass = "pass2" },
{ .id = "id3", .pass = "pass3" },
{ NULL },
};
struct account *a;
for (a = account_list; a.id; a++) {
....
}
Something like this is much easier to work with.

How to count 'on event' in CANoe Capl?

I'd like to count on event for 200ms.
I tried with this code in CANoe Capl but it's not working well.
I don't know what the problem is.
help me plz.
MainActivity.Capl
variables
{
int timerConditionChecker = 0;
int lockStatusMonitor = 0;
mstimer conutCheckTimer;
}
on timer conutCheckTimer
{
//do nothing
}
on sysvar_update sysvar::Frame2
{
if(timerConditionChecker == 0)
{
lockStatusMonitor++;
timerConditionChecker = 1;
setTimer(conutCheckTimer, 500);
}
else if(timerConditionChecker == 1)
{
if(timeToElapse(conutCheckTimer) > 200)
{
timerConditionChecker = 2;
}
else
{
lockStatusMonitor++;
}
}
else if(timerConditionChecker == 2)
{
timerConditionChecker = 3;
Write("lockStatusMonitorCount = %d",lockStatusMonitor);
}
else{}
}
What about this (I mostly used your variable names):
variables
{
int lockStatusMonitor = 0;
mstimer conutCheckTimer;
}
on timer conutCheckTimer
{
// Is called after 200ms and will output how often the sysvar was updated within these 200ms
Write("lockStatusMonitorCount = %d",lockStatusMonitor);
}
on sysvar_update sysvar::Frame2
{
if(isTimerActive(conutCheckTimer))
{
// In case the 200ms have already started, just count
lockStatusMonitor++;
}
else {
// Timer is not yet active, so start counting for the next 200ms now
lockStatusMonitor = 0; // or = 1 depending on whether your use case
setTimer(conutCheckTimer, 200);
}
}
Apart from that, using the CAPL debugger should help you to solve these kind of problems.

Using qsort() with Structs

I just started learning C and I'm still new to it.
In this program I'm working with an array of structs. The structs are:
typedef struct {
int day;
int month;
int year;
} Date;
typedef struct {
int serial_num;
char full_name[15];
Date *pDate;
} Person;
The array is Person *people.
Now I have two arrays of people and birth dates of those people (same indexes):
const char* names[MAX] = { "Sasson_Sassoni", "Pooh", "James_Bond", "Elvis_is_Alive", "Shilgiya", "Cleopatra", "Sissoo_VeSimmhoo" };
const int dates[MAX][COLS] = {
{ 10, 1, 1988 },
{ 12, 12, 1948 },
{ 4, 12, 1970 },
{ 11, 11, 1890 },
{ 11, 11, 1948 },
{ 1, 10, 1213 },
{ 12, 11, 1948 }
};
By using switch case, every time the user types 1 a person from the lists (Name and birthday) is added to the list people. Then if the user types 3, the list people should be sorted by date (oldest to youngest). So I wrote the following two functions:
void sortList(Person **people, int index) {
qsort(*people, index, sizeof(Person), intcmp);
}
int intcmp(const void *a, const void *b) {
Person *one = (Person *)a;
Person *two = (Person *)b;
int year1 = one->pDate->year;
int year2 = two->pDate->year;
int month1 = one->pDate->month;
int month2 = two->pDate->month;
int day1 = one->pDate->day;
int day2 = two->pDate->day;
if (year1 > year2)
return -1;
else if (year2 > year1)
return 1;
if (month1 > month2)
return -1;
else if (month2 > month1)
return 1;
if (day1 > day2)
return -1;
else if (day2 > day1)
return 1;
return 0;
}
But every time I get an error saying:
Exception thrown: read access violation.
one->pDate was nullptr.
Any help?
Thanks!
EDIT:
Further explanation: In order to insert the people to the array one by one, I made a variable called index and every time a person is added the index grows by one. So When calling the function qsort(), index is the number of people in the array. Also MAX=7, COLS=3, LEN=10. The function that adds people to the array is:
void addToList(Person **people, int *index, const char *names[MAX], const int dates[][COLS]) {
people[*index] = (Person *)malloc(sizeof(Person));
people[*index]->serial_num = *index + 1;
strcpy(people[*index]->full_name, names[*index]);
Date *temp = (Date *)malloc(sizeof(Date));
temp->day = dates[*index][0];
temp->month = dates[*index][1];
temp->year = dates[*index][2];
people[*index]->pDate = temp;
printf("%d %s %d/%d/%d \n", people[*index]->serial_num, people[*index]->full_name, people[*index]->pDate->day, people[*index]->pDate->month, people[*index]->pDate->year);
*index = *index + 1;
}
Your mcve is not complete but I think it's because you confuse pointer and struct:
void sortList(Person **people, int index) {
qsort(people, index, sizeof(Person *), intcmp);
// or qsort(people, index, sizeof *people, intcmp);
}
int intcmp(const void *a, const void *b) {
const Person *one = *(const Person **)a;
const Person *two = *(const Person **)b;

Pointers: Expression is not assignable

I'm writing a function whose purpose is to change the value of struct variables. I'm getting error messages that say the expressions toward the end of my first function are not assignable. How, then, do I have the function change the values of the daate structure?
Here's my code:
#include <stdio.h>
#include <stdbool.h>
struct date
{
int month;
int day;
int year;
};
struct date dateUpdate (struct date *dait) {
struct date tomorrow;
int numberOfDays (struct date d);
if (dait->day != numberOfDays (*dait) ) {
tomorrow.day = dait->day + 1;
tomorrow.month = dait->month;
tomorrow.year = dait->year;
}
else if ( dait->month == 12 ) { //end of year
tomorrow.day = 1;
tomorrow.month = 1;
tomorrow.year = dait->year + 1;
}
else { //end of month
tomorrow.day = 1;
tomorrow.month = dait->month + 1;
tomorrow.year = dait->year;
}
&dait->day = tomorrow.day;
&dait->month = tomorrow.month;
&dait->year = tomorrow.year;
return *dait;
}
//Function to find the number of days in a month;
int numberOfDays (struct date d)
{
int days;
bool isLeapYear (struct date d);
const int daysPerMonth[12] =
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if ( isLeapYear (d) && d.month == 2 )
days = 29;
else
days = daysPerMonth[d.month - 1];
return days;
}
}
int main (void) {
struct date daate;
daate.day = 21;
daate.month = 6;
daate.year = 2013;
dateUpdate(&daate);
printf("%d", daate.day);
}
The correct syntax (which you already used in the function) is the following
dait->day = tomorrow.day;
dait->month = tomorrow.month;
dait->year = tomorrow.year;
Take into account that instead of these three statements you could write simply
*dait = tomorrow;
dait is already a pointer, so &dait is a pointer to a pointer, and thus it has no fields to de-reference.
Solution: lose the & before dait.

Resources