1

Hi guys i've got a problem here with structs, the thing is, i've created a struct and then created a function that captures the employee details referenced from that struct. Now the problem comes when i try to call the function in the main. please give me some pointers as to how to call the function. the code is as follows:

typedef struct employeeType
{
    char name;
    int employeeNumber;
    float salary;
    float taxPercentage;
}EMPLOYEE;

void enterDetails(EMPLOYEE details)
{  
    FILE *file;
    file = fopen("employees.txt","w");
    if(file == NULL)
    {
        printf("File error!!!");
        exit(0);
    }
    else
    {
        fprintf(file,"%s",details);
    }
    fclose(file);

}

void main()
{ 
  enterDetails();
}

I don't know what parameters to pass to the function in the main

Gaurav
  • 28,447
  • 8
  • 50
  • 80
TaIra
  • 71
  • 1
  • 4

5 Answers5

1

I've annotated your code with some other issues to consider

typedef struct employeeType
{
     /* THIS IS ONLY ONE CHARACTER... SEEMS WRONG */
     /* should be 'char name[someMaxSize]', or 'char *name' */
    char name;  
    int employeeNumber;
    float salary;
    float taxPercentage;
}EMPLOYEE;

/* As pointed out by 'Cody Gray', this function is called 'enterDetails'
 * does it really need to have a parameter at all, or should it be responsible
 * for taking the details from the user?  Is it an appropriately 
 * named method for the task it's actually performing 
 * (would saveDetails be better for example)?
 */
void enterDetails(EMPLOYEE details)
{  
    FILE *file;
    file = fopen("employees.txt","w");
    if(file == NULL)
    {
        printf("File error!!!");
        exit(0);
    }
    else
    {
        /* THIS IS PASSING A STRUCTURE AS A STRING */
              /* You probably want to write out the individual fields instead */
              /* fprintf(file, "%s,%d", details.name, details.employeeNumber); etc */
        fprintf(file,"%s",details);  
    }
    fclose(file);

}

void main()
{ 
  EMPLOYEE details;   
  /* populate details somehow then pass it in to the function*/ 
  enterDetails(details);
}

You may also want to consider passing details into the function as a pointer, although that would change your function signature, it would mean that you're not pushing as much information onto the stack.

If you go with the pointer version then:

void enterDetails(EMPLOYEE details) 

would become

void enterDetails(EMPLOYEE *details) 

and the main would become:

void main()
{ 
  EMPLOYEE details;   
  /* populate details somehow then pass it in to the function as pointer */ 
  enterDetails(&details);
}

You would also need to change the way you use details within your function, but as I've already said, I believe your fprintf call is broken already.

forsvarir
  • 10,749
  • 6
  • 46
  • 77
0
void main()
{ 
  EMPLOYEE details;
   // get the value of element of struct from scanf or from other way
   printf("Enter Name : ");
   scanf("%s", details.name);  // same for others, change the format specifier according to their data type
  enterDetails(details);
}

And struct should be like

typedef struct employeeType
{
    char name[];  // should be an array or pointer, to store name
    int employeeNumber;
    float salary;
    float taxPercentage;
}EMPLOYEE;
Gaurav
  • 28,447
  • 8
  • 50
  • 80
  • @Gaurav i want to prompt for the details an write them to the file – TaIra Apr 28 '11 at 09:33
  • @Gaurav: You code is going to cause a crash. You've declared display.name as a pointer, but you're not initialising it to any memory before using it with scanf. Probably safer to go with an array. – forsvarir Apr 28 '11 at 09:46
  • thanks guys you really helped me alot, i might have named my function poorly and i aplologise for that. The thing is that my program has a main menu where you select an option to whether enter employee details or update them. So when you enter the details its suppose to write them to the file and when you update its suppose to first prompt for the name of the employee to update and then allow you to do your modifications, but now i also don't understand how to compare the contents of the file to the user input. PLEASE HELP GUYS I'M A NOVICE IN C – TaIra Apr 28 '11 at 10:46
  • @Talra: That's really a different question and should probably be posted as such, along with your code for writing to the file + any code you've written for reading from it. To compare the contents, you're going to have to open the file for reading and then read the records out. If you're writing them using fprintf, then you can probably read them using fscanf. Parameters to fscanf are supplied as pointers, so you'll need to prefix each one with an '&'. Then you can use something like 'strcmp' to check the name, and simple == to check the numeric inputs between the file and user input. – forsvarir Apr 28 '11 at 11:31
0

You can pass the pointer of the struct

void main()
{
    EMPLOYEE employee;
    .....
    enterDetails(&employee);
}

void enterDetails(EMPLOYEE *details)
{

}
J.S. Taylor
  • 771
  • 4
  • 7
0

You need to pass a reference, not a value... If you pass EMPLOYEE value as in the previous post, it will be copied, the copy will be modified, not the original

 void enterDetails(EMPLOYEE* emp) {
    // do stuffs
 }

 void main() {
   EMPLOYEE emp;
   enterDetails(&emp);
 }
Monkey
  • 1,838
  • 1
  • 17
  • 24
  • They're writing out to a file, not populating the structure, so the contents aren't modified either way by the function. – forsvarir Apr 28 '11 at 09:27
  • @forsvarir: So if writing out to a file, why does the `enterDetails` function accept a parameter at all? It seems like it should create an instance of the structure, fill it out, save it to a file, and return. – Cody Gray - on strike Apr 28 '11 at 09:33
  • @Cody Gray: A reasonable question. It could be poorly named, meaning enter the details into the file, or it could be that you're correct, and the enterDetails function should be asking for information in order to be able to have it to write to a file... I think the OPs in a better position to answer what they had in mind... – forsvarir Apr 28 '11 at 09:38
  • I believe passing a pointer is a win : can write to the structure, and the structure can be very fat, no problem, it's just a pointer we are passing – Monkey Apr 28 '11 at 09:47
0

The first problem is that your structure isn't correct. You can't store the employee's name on the name field since it's only one byte. You have to make it an array (it's simpler on this case) or a pointer to allocated memory.

If you want to make it an array, then you should define the maximum size of the array. In our example we will just make it 100 bytes, it will be more than enough to store any name.

#define MAX_NAME 100

typedef struct employeeType
{
    char name[MAX_NAME];
    int employeeNumber;
    float salary;
    float taxPercentage;
}EMPLOYEE;

Second, you're function naming is confusing. enterDetails should just populate the structure you passed. Third, your enter Details should accept a pointer to the EMPLOYEE structure. If you want to pass any value to a function that's going to change it's content, then you can only do that using pointers (or references if you're using C++ but that's basically a pointer). So enterDetails should be,

void enterDetails(EMPLOYEE *details)
{
    printf("\nEnter the employee's name ");
    scanf("%s", details->name); // this isn't secure since it doesn't perform bound checking.

    printf("\nEnter employee number ");
    scanf("%d", &details->employeeNumber);

    printf("\nEnter employee salary ");
    scanf("%f", &details->salary);

    printf("\nEnter tax percentage ");
    scanf("%f", &details->taxPercentage);

}

And finally, if you want to store the contents of the structure to a file that you want humans to read, then you should format the contents of the structure and dump it onto a file.

int writeToFile(EMPLOYEE *details) /* accepting the structure will work as well but it's faster and efficient to pass the structure's pointer */    
{
    FILE *file;

    file = fopen("employees.txt","w");
    if(file == NULL) {
       printf("File error!!!");
       return 0;
    }

    fprintf(file, "\nEmployee Name: %s", details->name);
    fprintf(file, "\nEmployee Number: %d", details->employeeNumber);
    fprintf(file, "\nSalary: %f", details->salary);
    fprintf(file, "\nTax Percentage: %f", details->taxPercentage);

    fclose(file)
    return 1;
}

And main

int main(void)
{
    EMPLOYEE details;

    enterDetails(&details); // passing the pointer here is a must
    if (!writeToFile(&details)) { // passing the pointer since it's faster
       printf("\nError writing to file");
       return 1;
    } else {
       printf("\nSuccess!");
       return 0;
    }
}

And in your case, you don't need to pass any parameters to main. But if you want to know how to pass parameters, then here is a quick example.

int main(int argc, char **argv)
{
    int i;

    for (i = 0; i < argc; i++)
        printf("\n%s", argv[i]);

    return 0;
}
shebaw
  • 1,775
  • 1
  • 13
  • 15
  • Your call to scanf for a numeric value is incorrect. This: scanf("%d", details->employeeNumber); should be passing in the address of the number, not the actual number, otherwise scanf doesn't know where to put the value. – forsvarir Apr 28 '11 at 13:00
  • @shebaw thanks it seems to work but when i run the program it only prompts for the name and employee number, when i press enter to proceed it halts and terminates. Thus not writing anything to the file, what could the problem be? – TaIra Apr 28 '11 at 16:41
  • @forsvarir can you give me an example of what you are saying please – TaIra Apr 28 '11 at 16:45
  • @Talra: change it to: scanf("%d", &details->employeeNumber); May need brackets, can't remember off had, if so it'll be: scanf("%d", &(details->employeeNumber)); – forsvarir Apr 28 '11 at 16:49
  • @forsvarir it seemed to have worked when i declared variables for the numeric input. Thanks for the pointer, highly appreciated. This is how i did it: void enterDetails(EMPLOYEE *details) { int empno; float sal; float tax; printf("Enter name: "); scanf("%s",details->name); printf("Enter employee number: "); scanf("%d",&empno); details->employeeNumber = empno; printf("Enter salary: "); scanf("%f",&sal); details->salary = sal; printf("Enter tax percentage (%): "); scanf("%f",&tax); details->taxPercentage = tax; } – TaIra Apr 28 '11 at 17:23
  • @Talra: That's great, glad you're making progress. If you feel that this question has been answered, then can you mark whichever answer helped you the most as accepted (by clicking the empty tick next to that answer). That gives a hint to anybody with a similar problem as to where to start. There's an overview of it in the FAQ. Good luck with your next challenge :) – forsvarir Apr 28 '11 at 21:31