0

I am trying to passing an array of structures to a function as an argument and change the values of the struct it self. The purpose of the code is to build an agenda. This specific function void newEvent(); should do what it says: adding a new event (new struct). Here is the code:

#include <stdio.h>
#include <stdlib.h>

#define MAX_LENGTH 100
#define N 12
#define HOURS 24
#define MINUTES 60

typedef struct appointment Appointment;

struct appointment {

    short int day;
    short int month;
    short int time[HOURS][MINUTES];
    char description[MAX_LENGTH];

};

Appointment meeting[N];

void newEvent (Appointment *meeting, int i, int event) {


    short int startingHour = 0, startingMinute = 0, endingHour = 0, endingMinute = 0;
    int j, z, flag = 0;

        printf("Enter a description of the appointment (max 100 characters): \n");
        fgets(meeting[i].description, MAX_LENGTH, stdin);

        printf("Date of the appointment (dd/mm): ");
        scanf("%hd/%hd", &meeting[i].day, &meeting[i].month);
        fflush(stdin);


    do {
        do {
            do {
                printf("Starts (hh:mm): ");
                scanf("%hd:%hd", &startingHour, &startingMinute);
                fflush(stdin);

                printf("Ends (hh:mm): ");
                scanf("%hd:%hd", &endingHour, &endingMinute);
                fflush(stdin);
            } while(startingHour > endingHour);
        } while((startingHour < 0 || startingHour > 23) || (endingHour < 0 || endingHour > 23) || (startingMinute < 0 || startingMinute > 59) || (endingMinute < 0 || endingMinute > 59));

        for (j = startingHour; j <= endingHour; j++) {
            for( z = startingMinute; z < MINUTES && flag == 0; z++) {
                if (j < endingHour) {
                    meeting[i].time[j][z] = 1;
                }
                if ((z > 0) && (z % (MINUTES - 1)) == 0) {
                    j++;
                    z = 0;
                }
                if (j == endingHour && z < endingMinute) {
                    meeting[i].time[j][z] = 1;
                }
                if ((j == endingHour) && (z == endingMinute)) {
                    flag = 1;
                }
            }
        }

        flag = 0;

        printf("\n");

        for(int a = 0; a < event; a++) {
            if((meeting[i].day == meeting[a].day) && (meeting[i].month == meeting[a].month)) {
                for (j = 0; j < HOURS; j++) {
                    for( z = 0; z < MINUTES; z++) {
                        if((meeting[i].time[j][z] == meeting[a].time[j][z]) && meeting[i].time[j][z] == 1) {
                            flag = 1;
                        }
                    }
                }
            }
        }
    } while(flag != 0);

    event++;
    flag = 0;


}






int main() {

    int ctrl = 0, event = 0, i, flag = 0, erase = 0;


    for(i = 0; i < N; i++) {
        for(int j = 0; j < HOURS; j++) {
            for(int z = 0; z < MINUTES; z++) {
                meeting[i].time[j][z] = 0;
            }
        }
    }

    do {
        system("cls");
        printf("1) Add an appointment\n");
        printf("2) Delete an appointment\n");
        printf("3) print month appointment\n");
        printf("4) Leave\n");

        printf("\nYour choice: ");
        scanf("%d", &ctrl);
        fflush(stdin);
        system("cls");

        switch (ctrl) {

        case 1:

            for (i = event; i < (event + 1); i++){
                newEvent(meeting, i, event);
            }

            system("PAUSE");
            break;

        case 2:
            printf("*** DELETING AN EVENT ***\n");
            printf("-------------------------\n");

            printf("Here down below is your agenda: \n");

            flag = 0;

            for(int i = 0; i < event; i++) {
                printf("Event n. %d description: \n%s\n", i + 1, meeting[i].description);
                printf("Date: %hd/%hd\n", meeting[i].day, meeting[i].month);
                for(int j = 0; j < HOURS; j++) {
                    for (int z = 0; z < MINUTES && flag == 0; z++) {
                        if(meeting[i].time[j][z] == 1) {
                            printf("Starts: %d:%d\n", j, z);
                            flag = 1;
                        }
                    }
                }

                flag = 0;

                for(int j = HOURS; j > 0; j--) {
                    for (int z = MINUTES; z >= 0 && flag == 0; z--) {
                        if(meeting[i].time[j][z] == 1) {
                            printf("Ends: %d:%d\n", j, z);
                            flag = 1;
                        }
                    }
                }

                flag = 0;

                printf("-------------------------------\n");
                printf("\n\n");
            }

            printf("Which event you would like to erase? \n");
            scanf("%d", &erase);

            for (int i = (erase - 1); i < event; i++) {
                meeting[i] = meeting[i+1];
                event--;
            }

            flag = 0;

            printf("Here down below your updated agenda: \n");

            for(int i = 0; i < event; i++) {
                printf("Event n. %d description: \n%s\n", i + 1, meeting[i].description);
                printf("Date: %hd/%hd\n", meeting[i].day, meeting[i].month);
                for(int j = 0; j < HOURS; j++) {
                    for (int z = 0; z < MINUTES && flag == 0; z++) {
                        if(meeting[i].time[j][z] == 1) {
                            printf("Starts: %d:%d\n", j, z);
                            flag = 1;
                        }
                    }
                }

                flag = 0;

                for(int j = HOURS; j > 0; j--) {
                    for (int z = MINUTES; z >= 0 && flag == 0; z--) {
                        if(meeting[i].time[j][z] == 1) {
                            printf("Ends: %d:%d\n", j, z);
                            flag = 1;
                        }
                    }
                }

                flag = 0;

                printf("-------------------------------\n");
                printf("\n\n");
            }

            system("PAUSE");
            break;

        case 3:

            printf("*** SHOWING ALL YOUR EVENTS ***\n");
            printf("-------------------------------\n");

            if(event == 0){
                printf("Nothing to show here :( \n");
            }

            flag = 0;

            for(int i = 0; i < event; i++) {
                printf("Event n. %d description: \n%s\n", i + 1, meeting[i].description);
                printf("Date: %hd/%hd\n", meeting[i].day, meeting[i].month);
                for(int j = 0; j < HOURS; j++) {
                    for (int z = 0; z < MINUTES && flag == 0; z++) {
                        if(meeting[i].time[j][z] == 1) {
                            printf("Starts: %d:%d\n", j, z);
                            flag = 1;
                        }
                    }
                }

                flag = 0;

                for(int j = HOURS; j > 0; j--) {
                    for (int z = MINUTES; z >= 0 && flag == 0; z--) {
                        if(meeting[i].time[j][z] == 1) {
                            printf("Ends: %d:%d\n", j, z);
                            flag = 1;
                        }
                    }
                }

                flag = 0;

                printf("-------------------------------\n");
                printf("\n\n");
            }


            system("PAUSE");
            break;
        }
    } while(ctrl != 4);


    return 0;
}

Unfortunately I got a warning which says warning: passing argument 1 of 'newEvent' from incompatible pointer type [-Wincompatible-pointer-types]

PS: The code i've putted here is a little bit simplified (you can see it from ...), but I think is enough to let people way better then me at coding in C understand where the problem is.

6
  • 2
    If newEvent only needs to work with one meeting, and it is given the space (an existing structure, which can be an element of an array of structures) for that meeting, then just make its parameter Appointment *meeting. The expression &meeting[i] is the address of a single structure, meeting[i], so it is an Appointment *. You do not need ** unless you want to pass not just the address of a thing but an address of a pointer to a thing. Commented Nov 26, 2020 at 13:40
  • I want to change the actual parameters of the struct itself so my idea was to pass the adress of the array of structs passing the adress of the pointer which points to each struct. Commented Nov 26, 2020 at 14:33
  • 1
    Re “passing the adress of the pointer which points to each struct”: An array is not a pointer. After Appointment meeting[N];, meeting is an identifier that designates the array. It is not a pointer to the array or a pointer to the first element of the array. &meeting is not the address of a pointer; it is the address of the array. When used in expressions other than as the operand of sizeof or unary &, meeting will be converted to a pointer to its first element, but it is not itself such a pointer. Passing &meeting does not pass an Appointment **. Commented Nov 26, 2020 at 14:41
  • 1
    Re “I want to change the actual parameters of the struct itself”: Structures do not have parameters. They have members. To enable a function to modify a structure (including its members), simply pass the address of the structure. meeting is an array of structures. meeting[i] is one structure. &meeting[i] is the address of one structure. To change meeting[i]. all newEvent needs is &meeting[i]. It does not need both meeting and i. Commented Nov 26, 2020 at 14:43
  • But if I pass only &meeting[i] to the function there is no way to refer to each struct of the array inside the function Commented Nov 26, 2020 at 17:23

3 Answers 3

1

When you pass an array you aren't passing by value, an easy way to visualize this is to think of scanf("%d", &var) vs scanf("%s", var). When you pass your array of structs, because it's just an array, you aren't passing by value:

So, this

void newEvent (Appointment **meeting, int i, int event)

Becomes

void newEvent (Appointment *meeting, int i, int event) or this void newEvent (Appointment meeting[], int i, int event) whichever you prefer for readability.

And this

newEvent(&meeting[i], i, event);

Becomes

newEvent(meeting, i, event);

Here is the code I used to test:

#include <stdio.h>

#define N 100
#define MAX_LENGTH 100

typedef struct appointment Appointment;

struct appointment {
     /*short int day;
     short int month;
     short int time[HOURS][MINUTES];*/
     char description[MAX_LENGTH];
};

void newEvent (Appointment *meeting, int i, int event) {

     printf("Enter a description of the appointment (max 100 characters): \n");
     fgets(meeting[i].description, MAX_LENGTH, stdin);
}

int main() {
    Appointment meeting[N];
    int event = 0;
    for (int i = 0; i < (event + 1); i++){
        newEvent(meeting, i, event);
    }
    printf("%s\n", meeting[0].description);
    
    return 0;

}

Your first problem is this:

printf("\nYour choice: ");
scanf("%d", &ctrl);
fflush(stdin);

You can't flush stdin so after you read an int into ctrl you are left with the \n on stdin, the resulting call to fgets receives that \n and continues. So do something like this to get that \n off of stdin.

char buf[10];
printf("\nYour choice: ");
fflush(stdout); /* always flush stdout if no newline */
fgets(buf, 10, stdin);
ctrl = atoi(buf);

I didn't go through the rest of the code, but what you were doing was storing that \n left on stdin to meeting[i].description

Sign up to request clarification or add additional context in comments.

10 Comments

I've tryed to do that but seems like the struct does not change. Do you know why?
I'll edit my answer to include the code I used to test, keep in mind that fgets captures the new line.
I do not know why but my program does not save anything into the fields of the structs. this printf("%s\n", meeting[0].description); will get me anything
Copy the code I pasted into the question into a new file, copy and run it, and share your errors.
Now it works but I've tried with my own entire code and when attempting to print all the structs into the array it will not show me anything. If you want I can paste the code here.
|
0

It depends on what you want to do exactly. By your question you want to pass the array of structs, so you want to do is: newEvent(meeting, i, event); and void newEvent (Appointment *meeting, int i, int event);. Like this you are passing the entire array and the index separately like you want to.

1 Comment

As I said before my purpose was to change the actual parameters of the struct itself so my idea was to pass the adress of the array of structs by passing the adress of the pointer at struct that is called meeting
0

So first, I think you should malloc your appointment array. Like this:

Appointment* meeting = (Appointment*)malloc(N * sizeof(Appointment));

Now your array will be in memory not in the stack. (dont forget to free(meeting) after you are done). I don't really get what int i is supposed to be in void newEvent, but you either give newEvent the whole array, or just one element meetings[i].

If you give the whole array u should do this:

void newEvent(Appointment* meetings, int i){
  //for example
  char* descrip = "...";
  strcpy(meetings[i].description, descrip);
  meetings[i].day = 15;
}
//to call the function:
newEvent(meetings, the meeting u want to change);

If you only give one element to the functuion u should do this:

void newEvent(Appointment* meetings){
  //for example
  char* descrip = "...";
  strcpy(meetings->description, descrip);
  meetings->day = 15;
}
//to call it
newEvent(&meetings[the meeting u want to change]);

In all cases if you want to initialize all of them u do this:

for (int i = 0; i < events; i++){
  newEvent(meetings, i);
  //or
  newEvent(&meetings[i]);
}

1 Comment

Thank you very much I'll try this one and see what happens

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.