0

first, I read all data from a file and put it in an array of pointer to struct and the add function is to add an employees data first last name etc... and then put in a pointer to struct with the data and return a pointer to the data by the function initdata and allocate more space in the heap with realloc then save all the data in the file but when i add a more than 2 or 3 people data the save function crashes i don't know why

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// iam working with an array of pointer to struct
typedef struct
{
    int day, year, month;
} date;

typedef struct
{
    int Id;
    float salary;
    char *f_name, *l_name, *adress, *email, *p_num;
    date * b_date;
} Data;

date* initdate(int day, int month, int year)
{
    date *x = (date*) malloc(sizeof(date));
    x->day = day;
    x->month = month;
    x->year = year;
    return x;
}

Data* InitData(int Id, char *p_num, float salary, char *f_name, char *l_name, char *adress, char *email, int day, int month, int year)
{
    Data *some = (Data*) malloc(sizeof(Data));
    some->adress = (char*) malloc(strlen(adress) + 1);
    some->email = (char*) malloc(strlen(email) + 1);
    some->l_name = (char*) malloc(strlen(l_name) + 1);
    some->f_name = (char*) malloc(strlen(f_name) + 1);
    some->p_num = (char*) malloc(strlen(p_num) + 1);
    some->Id = Id;
    some->salary = salary;
    strcpy(some->adress, adress);
    strcpy(some->f_name, f_name);
    strcpy(some->email, email);
    strcpy(some->l_name, l_name);
    strcpy(some->p_num, p_num);
    some->b_date = initdate(day, month, year);
    return some;
}

//that is the function to read from a file it has no problem  
Data **ReadFile(const char *FileName, int *i)
{
    FILE *x = fopen(FileName, "r");
    if (!x)
    {
        error(FileName);
        return NULL;
    }

    Data *st[100];
    char str[100];
    *i = 0;
    int count = 0;
    while (!feof(x))
    {
        fgets(str, 99, x);
        if (strcmp(str, "\n")) st[(*i) ++] = deserialize(str);
    }

    Data **flu = (Data **) malloc(sizeof(Data*) * (*i));
    int j;
    for (j = 0; j<*i; j++) flu[j] = st[j];
    fclose(x);
    return flu;
}

//and that is the function read a data of an employee to the file which has a problem

int Add_Emp(int *emp_num, Data **emp)
{
    int Id, day, year, month;
    float salary;
    char f_name[35], l_name[35], adress[40], email[40], p_num[30];
    getchar();
    printf("Enter Your First Name: ");
    gets(f_name);
    printf("Enter Your Last Name: ");
    gets(l_name);
    printf("Enter Your address: ");
    gets(adress);
    printf("Enter Your email: ");
    gets(email);
    printf("Enter Your Phone Number: ");
    gets(p_num);
    printf("Enter Your id: ");
    scanf("%d", &Id);
    printf("Enter Your salary: ");
    scanf("%f", &salary);
        printf("Enter The Date of Birth In This Order Day Month Year :");
        scanf("%d%d%d", &day, &month, &year);
    emp = (Data **) realloc(emp, ((*emp_num) + 1) *sizeof(Data*));
    if (emp == NULL) exit(2);
    emp[*emp_num] = InitData(Id, p_num, salary, f_name, l_name, adress, email, day, month, year);
    ++(*emp_num);
    return 1;
}

//and thats the function to save the final file 
void save(Data **x, int n, const char *file_name)
{
    int i;
    FILE *f = fopen(file_name, "w");
    if (!f) error(file_name);
    for (i = 0; i < n; i++)
    {
        char *a = serialize(x[i]);
        fprintf(f, "%s", a);
    }

    fclose(f);
    printf("progress saved \n");
    line();
}
int main()
{
      char F_Name[40];
      int Emp_Num;
      Data **emp;
      while(1){
      printf("Enter File Name:  ");
      gets(F_Name);
      emp=ReadFile(F_Name,&Emp_Num);
      if(emp) break;
      }
    int w;
    do
    {
        line();
        printf("\n1:search For An Employee.\n2:Add An Employees Data.\n3:Delete An Employees Data.\n4:Modify An Employee Data.\n5:Print All The Employees Data.\n6:Save All Your Changes.\n0:exit"); line();
        printf("Enter Your Choice: "); line();
        scanf("%d",&w);
        char l_name[15],FirstName[15];
        int t,Id,m;
        switch (w)
        {
         //  case 1 :   getchar(); printf("Enter The Employee Last Name: ");
            //          gets(l_name);  Search(emp,Emp_Num,l_name);
             //         break;
           case 2 :   Add_Emp(&Emp_Num,emp);tel=0;  break;

        //   case 3 :   getchar(); printf("Enter The Employee First Name: //");
                   //   gets(FirstName); line();
                   //   printf("Enter The Employee Last Name: ");
                   //   gets(l_name);  line(); //Delete(emp,&Emp_Num,l_name,FirstName); tel=0; break;
          // case 4 :  printf("Enter Id Of The Employee");line(); //scanf("%d",&Id);line(); modify2(emp,Emp_Num,Id); tel=0;break;
         //  case 5 :  line();printf("\n1:Sorted By Last Name.\n2:Sorted By //Salary.\n3:Sorted By Date Of Birth.");
                   //  line(); printf("Enter Your Choice: ");  line(); //scanf("%d",&t);if(!strstr(emp[Emp_Nu-1]-//>email,"\n"))strcat(emp[Emp_Num-1]->email,"\n");
                    // Sort(emp,Emp_Num,t); break;
           case 6 :  save(emp,Emp_Num,F_Name); tel=1;  break;
           //case 0 :  if(!tel){printf("All your changes since your last save //will be discarded. \n do you still wish to exit ?\n1.Yes\t2.No");line();
                   // scanf("%d",&m);}else m=1;Quit(Emp_Num,m,emp); break;
          default : fprintf(stderr,"Sorry %d Isn't a Valid Choice",w); break;
        }
    }while(1);
    return 0;
}
  • 2
    Note: [Why is “while ( !feof (file) )” always wrong?](https://stackoverflow.com/q/5431941) and [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/q/1694036) and [Do I cast the result of malloc?](https://stackoverflow.com/q/605845) – 001 Jan 10 '22 at 18:43
  • Are you actually using `ReadFile()`? There's no `main()` here so it's hard to tell which code you're actually using and which you're not. It could also easily be uninitialized variables that you haven't shown in the code. For example, is `emp_num` ever initialized? https://stackoverflow.com/help/minimal-reproducible-example – Bill Lynch Jan 10 '22 at 18:46
  • `realloc()` can return a different address than the one passed in. If this is the case in `Add_Emp()` you will be updating `emp_num` but not the original pointer. – 001 Jan 10 '22 at 18:57
  • Note that you can fold malloc/strcpy into a single call to strdup. – jarmod Jan 10 '22 at 18:59
  • @JohnnyMopp then what should i do – Anas Mostafa Jan 10 '22 at 19:00
  • 1
    @JohnnyMopp Well, these are three different categories of advice. (1: Error) `while(!feof())` is almost always semantically wrong and is typically a true mistake leading to programs that never work correctly. (2: Safety issue) Using `gets()` is what people did for decades. It is not *wrong* in the sense that it leads to programs that never work correctly. Instead it fails *only* for unexpected inputs and is a vulnerability for malicious inputs. (3: A question of style) Casting `malloc()` is not wrong or right and does not change the generated code. It is a matter of taste. – Peter - Reinstate Monica Jan 10 '22 at 19:01
  • 1
    @JohnnyMopp ok thanks – Anas Mostafa Jan 10 '22 at 19:02
  • Since you `exit(2);` on failure, there's no need to return an `int`. Instead, you could return the pointer: `Data** Add_Emp(int *emp_num, Data **emp)` and in main `emp = Add_Emp(&Emp_Num, emp)` – 001 Jan 10 '22 at 19:03
  • @JohnnyMopp ok thank u very much – Anas Mostafa Jan 10 '22 at 19:52

0 Answers0