Thread: How to add and delete items in a structure?

  1. #1
    Registered User
    Join Date
    May 2017
    Posts
    101

    How to add and delete items in a structure?

    I am working in a project and I would appreciate if someone can give me some orientation to add and delete items in a database created using a structure. The project consists in making a program to manage the clients of a medical center.

    So, I make an structure with each member variable. I declare a function to read all the data. I have to make a menu A, B, C, ... and after the user have registered all the clients, the menu should have an option to add more clients and another to delete existing clients. Is there any method to do that?

    Thank you in advance.

  2. #2
    Registered User
    Join Date
    May 2017
    Posts
    101
    Before you reply telling me I did nothing to research this, I found this link that is from this forum:

    Singly linked list - insert, remove, add, count source code - Cprogramming.com

    I can copy and adapt this but I don't understand how to put this in my code. There, only a structure is used and I have my structure with each variable members yet so my confusion would be what to do if I have another structure. I have only practice with one structure and do things with that structure, this is the first time I do things like adding records or delete records.

  3. #3
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    It depends on what you want to do with it. A linked list is a possible solution, although without further knowledge of your requirements I would say that a simple dynamic array is a possible solution too. Maybe even have it always sorted in order to take advantage of faster adding and deleting of items(the difference is noticeable only with large arrays).
    Devoted my life to programming...

  4. #4
    Registered User
    Join Date
    May 2017
    Posts
    101
    Hi GReaper. Researching through internet I was able to add a function to add a patience record to the list based on the structure I created. This is the code I have but is still in progress, just started yesterday, is incomplete and I should put on this several hours the next week, maybe I won't sleep. Please, if you noticed that the code I wrote until now is wrong, tell me:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>//not used yet but I guess I will use later
    #include <conio.h>//not used yet but I guess I will use later
    #define SIZE_PATIENCE 10//To put a number of records using the structure
    
    
    typedef struct {//this is the structure
        char name_patience[40];
        char rage[40];
        char gender[40];
        char observations[1024];
        char diagnosis[40];
        int day;//This code is for date of birth in format dd/mm/yy
        int month;//This code is for date of birth in format dd/mm/yy
        int year;//This code is for date of birth in format dd/mm/yy
    } tpatience;
    
    
    tpatience *first, *last, *next;
    
    
    void read_information(tpatience *p) {
        printf("Name of the patience: ");
        fgets(p->name_patience,SIZE_PATIENCE,stdin);
        printf("Insert the rage of the patience: ");
        fgets(p->rage,SIZE_PATIENCE,stdin);
        printf("Insert the gender of the patience: ");
        fgets(p->gender,SIZE_PATIENCE,stdin);
        printf("Insert the observations about the patience: ");
        fgets(p->observations,SIZE_PATIENCE,stdin);
        printf("Insert the diagnosis of the patience: ");
        fgets(p->diagnosis,SIZE_PATIENCE,stdin);
        printf("Insert the date of birth (dd/mm/yy)");
        scanf("%d%d%d", &m->day, &m->month, &m->year);//I'm not sure this is correct, I accept suggestions.
    }
    void add_patience() {
        tpatience *new;
        new=(tpatience*)malloc(sizeof(tpatience));
        if(new=NULL) {
            printf("There is not enough memory\n");
        }
        printf("Name of the patience: "); //this is a copy paste from the previous function
        fgets(p->name_patience,SIZE_PATIENCE,stdin);
        printf("Insert the rage of the patience: ");
        fgets(p->rage,SIZE_PATIENCE,stdin);
        printf("Insert the gender of the patience: ");
        fgets(p->gender,SIZE_PATIENCE,stdin);
        printf("Insert the observations about the patience: ");
        fgets(p->observations,SIZE_PATIENCE,stdin);
        printf("Insert the diagnosis of the patience: ");
        fgets(p->diagnosis,SIZE_PATIENCE,stdin);
        printf("Insert the date of birth (dd/mm/yy)");
        scanf("%d%d%d", &p->day, &p->month, &p->year);//As I said previously, I don't know if this is correct. I accept suggestions.
    
        new->next=NULL;
        if(next==NULL) {
            printf("First patience\n");
            first=new;
            last=new;
        } else {
            last->next=new;
            last=new;
        }
    }
    .
    .
    .
    .
    //To develop many other functions such as printing patiences, search patiences, ... I haven't still worked in that.
    .
    .
    .
    .
    int main()//To be developed in the next week
    {
        return 0;
    }
    I only have the structure, a function to read the data and a function to add a patience to the list. There are several more functions to be developed in the future: printing the list, create a menu, search a patience, delete a patience, modify a patience, ...
    Last edited by JorgeChemE; 05-28-2017 at 02:32 AM.

  5. #5
    Registered User
    Join Date
    May 2017
    Posts
    101
    I am now reading stuff to know what is the best way to write the structure. I know I will need a node (nobody taught me to do so) something like:

    Code:
    struct node{
        int data;
        struct node *next;
    } Node;
    but with typedef as well to avoid writing struct over and over... Any suggestion will be appreciated.

  6. #6
    Registered User
    Join Date
    Sep 2014
    Posts
    364
    Avoid magic numbers! As you can see, i have defines for all members.
    Don't cast the returned value of malloc!
    If you output lines without newlines, it can be that the lines will not shown at the console, because the console is line buffered.
    You can force the output with fflush.
    'day', 'month' and 'year' are values that form a date. I have written a typedef 'date' for it and tpatience has a member with this type.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define NAME_MAX 64
    #define RAGE_MAX 64
    #define GENDER_MAX 64
    #define OBSERV_MAX 1024
    #define DIAG_MAX 64
    #define BUFFER_MAX 64
    
    typedef struct {
        int day;
        int month;
        int year;
    } date;
    
    typedef struct patience {
        char name[NAME_MAX];
        char rage[RAGE_MAX];
        char gender[GENDER_MAX];
        char observations[OBSERV_MAX];
        char diagnosis[DIAG_MAX];
        date birth;
        struct patience *next;
    } tpatience;
    
    tpatience *add_patience(tpatience **first, tpatience **last) {
    
        tpatience *new;
        char buffer[BUFFER_MAX];
    
        if ((new = malloc(sizeof(*new))) == NULL) {
            fprintf(stderr, "There is not enough memory!\n");
            return NULL;
        }
    
        printf("Name of the patience: ");
        fflush(stdout);
        fgets(new->name, NAME_MAX, stdin);
    
        printf("Insert the rage of the patience: ");
        fflush(stdout);
        fgets(new->rage, RAGE_MAX, stdin);
    
        printf("Insert the gender of the patience: ");
        fflush(stdout);
        fgets(new->gender, GENDER_MAX, stdin);
    
        printf("Insert the observations about the patience: ");
        fflush(stdout);
        fgets(new->observations, OBSERV_MAX, stdin);
    
        printf("Insert the diagnosis of the patience: ");
        fflush(stdout);
        fgets(new->diagnosis, DIAG_MAX, stdin);
    
        printf("Insert the date of birth (dd/mm/yy): ");
        fflush(stdout);
        fgets(buffer, BUFFER_MAX, stdin);
        sscanf(buffer, "%d/%d/%d", &new->birth.day, &new->birth.month, &new->birth.year);
     
        new->next=NULL;
        if(*first == NULL) {
            printf("First patience\n");
            *first = new;
            *last = new;
        } else {
            (*last)->next = new;
            *last = new;
        }
        return new;
    }
    
    void free_patience(tpatience **first, tpatience **last) {
    
        tpatience *prev, *now;
    
        if (*first == NULL) return; // no linked list given
    
        now = *first;
        while (now) {
            prev = now;
            now = now->next;
            free(prev);
        }
        
        *first = *last = NULL;
    }
    
    int main (void) {
    
        tpatience *first = NULL, *last = NULL;
    
        if (add_patience(&first, &last) == NULL) {
            fprintf(stderr, "nothing added\n");
        }
    
        free_patience(&first, &last);
        return 0;
    }
    Other have classes, we are class

  7. #7
    Registered User
    Join Date
    May 2017
    Posts
    101
    Hi WoodStokk, thank you very much for your help. You did solve me a lot of questions, mainly in structure definition. I will study it and come back if something is wrong.

    Thank you!

  8. #8
    Registered User
    Join Date
    May 2017
    Posts
    101
    I have a problem to print the list of the patiences... I am not able to understand how to consider the patiences added. This is my code for that function:

    Code:
    void list_patiences(tpatience *ptr, int SIZE_PATIENCES) {
        for (int i=0; i<SIZE_PATIENCES; i++) {
            printf("\n%s", (ptr+i)->name);
        }
    }
    I input the number of patiences through keyboard:

    Code:
    int main ()
    
        int SIZE_PATIENCES;
    
    
        printf("Insert the name of patiences: ");
        scanf("%d", &SIZE_PATIENCES);
    Of course this is a part of the code, the relevant part. I understand the problem. When I attempt to print the patiences, after adding a new patience, the function void list_patiences(tpatience *ptr, int SIZE_PATIENCES) still prints the same patience that I had before adding a new one. How to consider the new patience in this print?

    Thank you in advance.

  9. #9
    Registered User
    Join Date
    May 2017
    Posts
    101
    Quote Originally Posted by JorgeChemE View Post
    I have a problem to print the list of the patiences... I am not able to understand how to consider the patiences added. This is my code for that function:

    Code:
    void list_patiences(tpatience *ptr, int SIZE_PATIENCES) {
        for (int i=0; i<SIZE_PATIENCES; i++) {
            printf("\n%s", (ptr+i)->name);
        }
    }
    I input the number of patiences through keyboard:

    Code:
    int main ()
    
        int SIZE_PATIENCES;
    
    
        printf("Insert the name of patiences: ");
        scanf("%d", &SIZE_PATIENCES);
    Of course this is a part of the code, the relevant part. I understand the problem. When I attempt to print the patiences, after adding a new patience, the function void list_patiences(tpatience *ptr, int SIZE_PATIENCES) still prints the same patience that I had before adding a new one. How to consider the new patience in this print?

    Thank you in advance.
    I managed to solve it by myself since is not a good solution, at least works. I created two functions:

    Code:
    void list_patiences1(tpatience *ptr, int SIZE_PATIENCES) {
        for (int i=0; i<SIZE_PATIENCES; i++) {
            printf("\n%s", (ptr+i)->name);
        }
    }
    void list_patiences2(tpatience *ptr) {
        int cont=0;
        ptr=first;
        while (ptr!=NULL) {
            printf("\n%s", ptr->name);
            ptr=ptr->next;
            cont++;
        }
    }
    Then in int main () in my menu...

    Code:
            case 'B':
                list_patiences1(patiences,SIZE_PATIENCES);
                list_patiences2(first);
                break;
    I know surely there is a better way. I would please require help to find a way to delete patiences from this list. I will research by my way in the meantime.

  10. #10
    Registered User
    Join Date
    Sep 2014
    Posts
    364
    This isn't posible, because you have a linked list and not a array.
    Here are 2 functions to output one patient and the full list.


    Code:
    void show_patience(tpatience *p) {
     
        if (p == NULL) {
            fprintf(stderr, "no pointer given!\n");
            return;
        }
    
        printf("Name: %s\n", p->name);
        printf("Rage: %s\n", p->rage);
        printf("Gender: %s\n", p->gender);
        printf("Observations: %s\n", p->observations);
        printf("Diagnosis: %s\n", p->diagnosis);
        printf("Birth: %d/%d/%d\n", p->birth.day, p->birth.month, p->birth.year);
    }
    
    void show_all_patience(tpatience *first) {
     
        tpatience *now = first;
        if (now == NULL) {
            fprintf(stderr, "no pointer given!\n");
            return;
        }
    
        while (now) {
            show_patience(now);
            now = now->next;
        }
    }

    If you want show the last inserted patient, you can call show_patience with the last-pointer from main-function.
    Code:
    …
        show_patience(last);
    …
    If you want to output the full list, you can call show_all_patience with the first-pointer from main-function.
    Code:
    …
        show_all_patience(first);
    …
    Last edited by WoodSTokk; 05-29-2017 at 09:52 AM.
    Other have classes, we are class

  11. #11
    Registered User
    Join Date
    May 2017
    Posts
    101
    I will study your solution. SIZE_PATIENTS (sorry... I am translating code again, is patients not patiences...) is a number I declared in int main() to read through keyboard. The idea was asking for the number of patients to insert the data, I have a function to read all this data, another to insert more patients and two functions to print patients: the first function prints patients of the first function (to read patients) and the second function prints only the patients inserted through the function insert patients. So, in the menu, basically I am doing: print patients that have been read at first + print patients that have been inserted through the function to insert patients. I am really worried about when I finally know how to delete them, will be imposible to print that considerating:
    1) patients inserted through read patients function
    2) patients inserted through insert patients function
    3) patients deleted with the hypothetical future function to delete patients.

    This is a hell!

  12. #12
    Registered User
    Join Date
    Sep 2014
    Posts
    364
    Quote Originally Posted by JorgeChemE View Post
    This is a hell!
    This is only a Hell if you are new in the technique of linked list.
    If you have programmed some weeks (or months) with it, you collect practice and linked lists will be a absolutly normal thing for you.
    Here is the logic of linked list (and also double linked).


    Linked List:
    You can allways start at 'head' and jump from struct to struct (with '*next') until you find what you searching for.
    'tail' is only a helper for append new struct, but you can not go backward.
    Code:
    .        –––––––     –––––––     –––––––     –––––––     –––––––
    *head-->| data  |   | data  |   | data  |   | data  |   | data  |<--*tail
            | …     |   | …     |   | …     |   | …     |   | …     |
            | *next |-->| *next |-->| *next |-->| *next |-->| *next |--> NULL
             –––––––     –––––––     –––––––     –––––––     –––––––

    Double Linked List:
    You can start at 'head' and jump forward (with '*next') or you can start at 'tail' and jump backward (with '*prev') until you find what you searching for.
    Code:
    .        –––––––     –––––––     –––––––     –––––––     –––––––
    *head-->| data  |   | data  |   | data  |   | data  |   | data  |<--*tail
            | …     |   | …     |   | …     |   | …     |   | …     |
            | *next |-->| *next |-->| *next |-->| *next |-->| *next |--> NULL
    NULL <--| *prev |<--| *prev |<--| *prev |<--| *prev |<--| *prev |
             –––––––     –––––––     –––––––     –––––––     –––––––

    It is very important that you never lose a pointer! If you lose a pointer you can never free the allocated memory!
    A lost pointer is automaticly a memory leak!
    Last edited by WoodSTokk; 05-29-2017 at 11:03 AM.
    Other have classes, we are class

  13. #13
    Registered User
    Join Date
    May 2017
    Posts
    101
    Quite similar as something I found to start working with delete function:

    Singly linked list - insert, remove, add, count source code - Cprogramming.com

    This code is from this forum. I will adapt it to my program. The problem is that this code only delete an int because his structure has only a member variable. As you know, I have a lot of variable members, how to delete all the remaining variables?

    Edited: I provided a trust code from this website.
    Last edited by JorgeChemE; 05-29-2017 at 11:38 AM.

  14. #14
    Registered User
    Join Date
    Sep 2014
    Posts
    364
    Quote Originally Posted by JorgeChemE View Post
    The problem is that this code only delete an int because his structure has only a member variable. As you know, I have a lot of variable members, how to delete all the remaining variables?
    You misunderstood a little bit.
    Code:
    tpatience *new;
    new = malloc(sizeof(*new));
    With this code, you allocate memory for a complete struct (with all members).
    Code:
    // new is a pointer to a allocated memory for a struct
    free(new);
    With this code, you free the memory that has the struct occupied (with all members).
    free doesn't release a single member, it free the whole struct!
    Other have classes, we are class

  15. #15
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I don't think you need to worry about the data. If you look at the code, the delete function will only ever use the next member, and calling free() will work because you previously used malloc() to allocate your structure. The way I think about it, the only time you will need to worry about the data is when you sort or search by some criterion which is exactly what your code did not show how to do. In that case, you can write a general sort or search, but use a comparison function in your code.

    Code:
    node *search(tpatience *list, int (*compare) (tpatience *, tpatience));
    /* call compare(a, b) in here. */
    
    int compareDate(tpatience *left, tpatience *right)
    /*    RETURN RESULT: 0 for equal, <0 if left comes before right, >0 if right comes before left.
           
           NOTES:
           strcmp() probably does it safely enough, note however that this is not y2k safe -
           people born on or after 2000 will be sorted with people born on or after 1900.
           ex: 05/10/20 could mean 1920 or 2020.
    */
    {
       char date1[] = "ddmmyy";
       char date2[] = "ddmmyy";
       sprintf(date1, "%02d%02d%02d", left->birth->day, left->birth->month, left->birth->year);
       sprintf(date2, "%02d%02d%02d", right->birth->day, right->birth->month, right->birth->year);
       return strcmp(date1, date2);
    }
    
    /* call it this way: */ found = search(head, compareDate);
    Other criterion will need functions that work the same way.
    Last edited by whiteflags; 05-29-2017 at 01:27 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 08-25-2013, 05:09 AM
  2. using delete on a structure pointer
    By spongefreddie in forum C++ Programming
    Replies: 9
    Last Post: 07-06-2011, 12:12 PM
  3. Delete records in Structure
    By Myrren in forum C Programming
    Replies: 6
    Last Post: 11-19-2010, 02:15 AM
  4. Delete All Items In A Linked List
    By Khellendros in forum C++ Programming
    Replies: 6
    Last Post: 02-09-2009, 01:22 AM
  5. Delete duplicate items in an array
    By chaos in forum C Programming
    Replies: 4
    Last Post: 06-16-2005, 02:51 PM

Tags for this Thread