I have two structs, Employee and EmployeeList. EmployeeList has the struct for Employee inside of it.
typedef struct{
int id;
char name[50];
char position[15];
double salary;
}Employee;
typedef struct{
Employee employees[LEN];
int count;
}EmployeeList;
LEN is a sentinel value defined previously. I then have an array of employees with their employee data inside, separated by |
char employData[6][100] = {
"1|Archer, Malory|CEO|500000.0",
"2|Archer, Sterling|Agent|250000.0",
"3|Kane, Lana|Agent|300000.0",
"4|Figus, Ceril|Accountant|100000.0",
"5|Tunt, Cheryl|Secretary|65000.0",
"6|Poovey, Pam|HR|85000.0"
};
My goal is to take this information given in the array, and first feed it into the EmployeeList struct, I've already separated each line of data but I'm struggling with how to actually store the data I got into that specific aspect from the struct. The assignment also wants me to store this information in the EmployeeList struct first, whereas I feel it could be more efficient if I could just store all the information in the Employee struct as I get it. I am also supposed to count every line of the employees, which I have already done. This is what I have so far.
EmployeeList read_employees(char emList[][100]){
int i = 0;
int j = 0;
EmployeeList el1;
for(i = 0; i<6; i ){
char* token = strtok(emList[i], "|");
strcpy(e1.id, emList[i]);
//This is the portion that I can't figure out
while(token != NULL){
printf( "%s ", token);
token = strtok(NULL, "|");
}
printf( "\n");
}
el1.count = i;
//printf("%s", el1.employees);
}
Thank you for anyone who reads or gives their input!
CodePudding user response:
If the variable el1
is declared like
EmployeeList el1;
then you need to write for example
el1.employees[i].id = atoi( token );
Initially you should initialize the object el1
with zeroes as for example
EmployeeList el1 = { 0 };
or like
EmployeeList el1 = { { 0 } };
CodePudding user response:
So you have your data in a list of tokens and you want to put this info into its appropriate containers, the elements of the struct. The information always comes in in the same order which makes things much easier, you can always assume the first token is the employee #, Second is the name, etc.
You can do this manually, ie.:
EmployeeList.employee[0].id = *token
token = strtok(NULL, "|");
strcpy(EmployeeList.employee[0].name, token );
etc.
Or you can do this smarter using a case switch statement right before where you print the values:
switch(counter)
case 0:
EmployeeList.employee[EmployeeList.count].id = *token
break;
case 1:
strcpy(EmployeeList.employee[EmployeeList.count].name, token );
break;
counter ;
the second is probably how I'd do it for a work problem, but I'm assuming you can get away with the first method, just moving the values into their proper place
Edit - this answer is incomplete - this is assuming you have all of your data in proper forms. You will need to use atoi() and initialize your structs as mentioned in the other answer
CodePudding user response:
strcpy
is used to copy a string from one distinct memory location to another (and it is up to the programmer to ensure the destination location is large enough).
It cannot be used to parse an integer as in:
strcpy(e1.id, emList[i]);
Though, your compiler should issue a rather firm error here, along the lines of:
error: use of undeclared identifier 'e1'
You should be accessing each Employee
structure in the employees
array member of el1
. Some examples:
el1.employees[0].id = 5;
strcpy(el1.employees[2].name, "Bob");
To parse a number from a string, you can use standard library functions such as atoi
or strtol
for integers, and atof
or strtod
for floating point numbers.
Some examples:
int a = atoi("42");
long b = strtol("1234567890", NULL, 10);
double c = strtod("123.456", NULL);
If you want to use strtok
, know that each token is of course a string. You can unroll your loop and think about what needs to be done with each token
char buf[] = "1|Archer, Malory|CEO|500000.0";
char *id_token = strtok(buf, "|");
char *name_token = strtok(NULL, "|");
char *position_token = strtok(NULL, "|");
char *salary_token = strtok(NULL, "|");
as some of these should be copied as strings, and some should be parsed as numbers.
The condition here,
for(i = 0; i<6; i ){
means emList
must always contain exactly 6 strings, which is rather rigid.
Consider passing a length parameter to the function:
EmployeeList read_employees(char **emList, size_t length) {
/* ... */
for (size_t i = 0; i < length && i < LEN; i ) {
The easiest example of this pattern is in the signature of main
with int argc
and char **argv
.