does any one know how to solve?

Hello experts,
Here is my code.I can create the database.But I also want it to see standard output.Please see the blocked code.If i use them they show me weired symbols.

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

struct date {
    int month;
    int day;
    int year;
    };
struct empRec{
    char name[25];
    char room[10];
    int jobLevel;
    struct date startDate;
    };
int main(){
    FILE *data;
    static struct empRec employee[1000]={
                {"Peter North","4B-208",35400,{10,11,1983}}
               
            };

    int entries=6;
    if((data=fopen("database","w"))==NULL){
                fprintf(stderr,"Can't Create database\n");
                exit(1);
                }
    if(fwrite(employee,sizeof(struct empRec),entries,data)!=entries){
                fprintf(stderr,"WRITE ERROR\n");
                exit(1);
                }
    
    /*char buf[1024];
    rewind(data);
    fread(buf,sizeof(struct empRec),6,data);
    printf("%s\n",buf);
    */
    fclose(data);
    printf("Created database\n");
    exit(0);
}

There are several points about you code I don't agree. Instead of pointing all of them, I just rewrote your code into something that works and fits your need.

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

struct date {
    int month;
    int day;
    int year;
    };
struct empRec{
    char name[25];
    char room[10];
    int jobLevel;
    struct date startDate;
    };

int main(){
    FILE *data;
    struct empRec employee= {"Peter North","4B-208",35400,{10,11,1983}};


        struct empRec employee2;

    if((data=fopen("database","w+"))==NULL){
                fprintf(stderr,"Can't Create database\n");
                exit(1);
                }
    if(fwrite(&employee,sizeof(struct empRec),1,data)!=1){
                fprintf(stderr,"WRITE ERROR\n");
                exit(1);
                }

    rewind(data);
    fread(&employee2,sizeof(struct empRec),1,data);
    printf("%s %s %d %d %d %d\n", employee2.name, employee2.room, employee2.jobLevel, employee2.startDate.month, employee2.startDate.day, employee2.startDate.year);
    fclose(data);
    printf("Created database\n");
    exit(0);
}

The database file will always have "weird symbols" because int's are stored as binary data. Not a problem though.
Let me know if I misunderstood something.

Thkx for giving your valuable time.Now it works fine .

Do you know why for loop does not work?

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

struct date {
    int month;
    int day;
    int year;
    };
struct empRec{
    char name[25];
    char room[10];
    int jobLevel;
    struct date startDate;
    };

int main(){
    FILE *data;
    static struct empRec employee[1000]={
                {"Peter North","4B-208",35400,{10,11,1983}},
                {"John Musa","2B-118",25400,{07,10,1993}},
                {"Paula Jeminova","1A-506",18700,{02,1,1990}},
                {"Patricia Silver","6C-123",52100,{14,21,2000}},
                {"Robert mill","4D-318",42100,{01,19,2008}},
            };

        struct empRec employee2;

    if((data=fopen("database","w+"))==NULL){
                fprintf(stderr,"Can't Create database\n");
                exit(1);
                }
    if(fwrite(&employee,sizeof(struct empRec),1,data)!=1){
                fprintf(stderr,"WRITE ERROR\n");
                exit(1);
                }

    rewind(data);
    fread(&employee,sizeof(struct empRec),1,data);
    int n;
    for (n = 0; n < employee.length; n++) { 
    printf("%s %s %d %d %d %d\n", employee[n].name, employee[n].room, employee[n].jobLevel, employee[n].startDate.month, employee[n].startDate.day, employee[n].startDate.year);
    
    }    
    fclose(data);
    printf("Created database\n");
    exit(0);
}

I'm not sure you understand exactly what's going on there.

fwrite(&employee,sizeof(struct empRec),1,data)

the 3rd parameter of this function tells you how many sizeof(struct empRec) should be written to data file pointer. So if you had '3' instead of '1' it would write sizeof(struct empRec)*3 bytes of employee to data file pointer (would write 3 entries of employee array struct).

Another thing, employee.length ? There is no member length in struct empRec. If you wanna know the number of entries in that array struct put the number explicitly or add something like

    static struct empRec employee[1000]={
                {"Peter North","4B-208",35400,{10,11,1983}},
                {"John Musa","2B-118",25400,{07,10,1993}},
                {"Paula Jeminova","1A-506",18700,{02,1,1990}},
                {"Patricia Silver","6C-123",52100,{14,21,2000}},
                {"Robert mill","4D-318",42100,{01,19,2008}},
                {"\0", "\0", 0, {0,0,0}},

and create a function to count the number of elements until the first byte of name is '\0'.

This information is really helpful.thkx

Don't need a for loop to go through all the record entries...when EOF is reached fread() returns zero for the number of items read and that can be used as a terminal condition.
You don't need to initialize a 1000 element employee array when you will be using only a few elements of it. The size of the employee array is known completely at compile time using the sizeof operator after the employee array has been initialized. See source changes highlighted in red.

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

struct date
{
    int month;
    int day;
    int year;
};
struct empRec
{
    char name[25];
    char room[10];
    int jobLevel;
    struct date startDate;
};

int main()
{
    int entries;        /* number of employee records */
    FILE *data;
    static struct empRec employee[] =
    {
        {"Peter North","4B-208",35400,{10,11,1983}},
        {"John Musa","2B-118",25400,{07,10,1993}},
        {"Paula Jeminova","1A-506",18700,{02,1,1990}},
        {"Patricia Silver","6C-123",52100,{14,21,2000}},
        {"Robert mill","4D-318",42100,{01,19,2008}}
    };

    struct empRec employee2;
    entries = (sizeof employee / sizeof employee[0]);

    if ((data = fopen("database","w+")) == NULL) {
        fprintf(stderr,"Can't Create database\n");
        exit(1);
    }
    if (fwrite(&employee,sizeof(struct empRec), entries, data) != entries) {
        fprintf(stderr,"WRITE ERROR\n");
        exit(1);
    }
    rewind(data);

    /* Replace for loop with the while loop below */
    while(fread(&employee2,sizeof(struct empRec), 1, data) == 1)
        printf("%s %s %d %d %d %d\n", employee2.name, employee2.room, employee2.jobLevel,
            employee2.startDate.month, employee2.startDate.day, employee2.startDate.year);

    fclose(data);
    printf("Created database\n");
    exit(0);
}

IMHO that kind of solution fits best in const cases because in this case the original poster might want to add more entries in employee array struct from say, user input?

I thought I should bring this up because mlhazan doesn't seem to be a very experienced C programmer. Anyhow, I might be wrong and shamrock's solution could be exactly what mlhazan is looking for.

Imho that solution should be used for both static and dynamic cases. It's not advisable to create a 1000 element array on the stack and end up using only a small portion of it. Knowledge of sizeof operator is even more important if the code was accepting user input from the keyboard because in that scenario calls to malloc() printf() and fgets() have to be interleaved together in order to fill up a single empRec structure though its size should be known beforehand.

I agree with static cases when the total number of structs inside employee is known and sizeof() returns the whole size of the array so if we want to know the number of entries we just have to divide sizeof(employee) for sizeof(struct empRec). But in dynamic cases when the user wishes to add more entries in employee array struct, if the array (employee) is bigger (1000 structs) than the number of entries (struct empRec) it has, sizeof() will not help to determine the number of entries because it will give us the size of those 1000 structs and we just want to know those we're using. Also if pointers/malloc() are used, sizeof() won't be of any help I guess.

    static struct empRec employee[10] =
    {
        {"Peter North","4B-208",35400,{10,11,1983}},
        {"John Musa","2B-118",25400,{07,10,1993}},
        {"Paula Jeminova","1A-506",18700,{02,1,1990}},
        {"Patricia Silver","6C-123",52100,{14,21,2000}},
        {"Robert mill","4D-318",42100,{01,19,2008}}
    }

In this case, if we would want to add a few more entries dynamically we could not determine the number of existing entries (5) using sizeof(), because sizeof(employee) is the same as saying sizeof(struct empRec)*10.

This is why I was advising the original poster to use a NULL/empty struct reference as the final entry so the number of entries could be calculated by counting structs until an empty one was found.

I also agree that having 1000 entries is far too much, but I was not arguing about that. Anyway, how do you use sizeof() in dynamic cases?

The problem with static cases is that you are restricted in the size of the database that can be created. Declaring a 1000 element array implies that the database can't have more than 1000 records in it atleast there is no easy way to alter the number of records it can have short of modifying the array definition in the source code and re-compiling.

the sizeof operator returns the allocated size instead of the used size for any object...so in the above case it will return the "sizeof one empRec structure times 10".

That would work only for static cases and in scenario where the last entry was NULL it implies wasting memory since only 5 out of 10 structs can be used.

Determine the size of one empRec structure and malloc'ate memory for it before adding a new record. This way the database size is not limited by the number of elements in the array.
The code snippet below can be put inside a loop to allocate space for a block of at least empRec size bytes followed by prompting the user for input and storing it in one of the elements of the empRec structure members.

pointer_to_empRec_object = malloc(sizeof(struct empRec));

while () {    /* while loop to capture user input */
    printf("get emp name ");
    fgets()   /* store emp name input above */
    printf("get emp room ");
    fgets()   /* store emp room */
    printf("get emp start date ");
    fgets()   /* store emp start date */
}   /* end of while loop */

Sure. For the situation at hand static cases should only be used if performance really matters. If there is a need to expand the number of entries to an unknown value we should use dynamic algorithms (linked list implementation for example)

Thus confirming that your initial solution can't be used in both static/dynamic cases like I said. If you have a static case that needs expanding sizeof() will not help to determine the number of entries and if you have a dynamic case sizeof() will not help too.

Remember that we're talking about an array of structs so either we use linked lists or we would have to malloc() a pointer of pointers to struct empRec.

Anyway I was just saying that the initial solution you posted will fit best in static cases which don't need expansion because you used sizeof() to calculate the number of entries and that wouldn't be possible if there were more entries in the array struct than those in use.

On the contrary if performance really matters one would go with a dynamic solution in order to minimize the overhead of allocating a very large memory segment and using only a small portion of it. A static solution is not optimized in terms of memory management.

Yes a linked list should be used for dynamic cases as it allows searching the database and removing entries from it whereas a sequential list like the one used by the o/p allows only insertions in the form of appends.

Why would you need to expand a static array. Don't you think that's an oxymoron? If you need to expand an array it becomes dynamic by default. The only case where that solution won't work is the gray scenario you suggested where the number of allocated entries is more than the used ones; as in the case below where the array has 10 entries allocated and only 5 are used. :confused:

static struct empRec employee[10] =
{
     {"Peter North","4B-208",35400,{10,11,1983}},
     {"John Musa","2B-118",25400,{07,10,1993}},
     {"Paula Jeminova","1A-506",18700,{02,1,1990}},
     {"Patricia Silver","6C-123",52100,{14,21,2000}},
     {"Robert mill","4D-318",42100,{01,19,2008}}
}

You won't need double level of indirection...the memory returned by malloc() will be assigned to a pointer to an object of type struct empRec that is a single level of indirection. My earlier post showed that scenario.

Imho the only case which it doesn't fit is the gray case you proposed where the number of allocated entries is more than the ones used.

I think we're failing to communicate due to my poor English.

This is a question of circumstance, memory access speed is generally the same for both static and dynamic memory but if you're creating a program where (malloc()ing) and free()ing entries happens too often a static implementation (with proper algorithms to avoid overflows) should be prefered.

I was not referring about expanding the array itself! I was talking about expanding the number of entries inside the array (so called "gray scenario"). The gray situation has some indications. For instance, if the proper algorithm (avoid bound overflows) is used and we're going to add and remove many entries at a time (for example, buffer purposes).

Yes I never said it was imperative I just said that you where proposing a one-level solution when the user was having a two-leveled problem. I just said that pointer you refer would have to be linked inside a list (linked lists) to fulfill the user's problem or be inside a double level pointer.

IMHO the best solution is not generally applied to every case hence there is no point saying "dynamic is the best way" or "static is the best way". The best solution is that which fits the requirements and has best performance.

Guess we are on the same page now :b: