Reputation: 5446
I have a nested array of structures in the following form:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
char* e_name;
char* e_lastname;
}emp_name;
typedef struct
{
emp_name name;
int id;
}emp;
int main(int argc, char *argv[])
{
int i;
int cod=100;
emp job[3];
for (i=0;i<3;i++)
{
scanf("%s",&job[i].emp.e_lastname);
job[i].id=cod;
cod++;
}
for (i=0;i<3;i++)
{
printf("%s",job[i].emp.e_lastname);
printf("%d\n",job[i].id);
}
system("PAUSE");
return 0;
}
but the program hangs in the printing part, why is that? Thanks
Upvotes: 1
Views: 3299
Reputation: 1372
You really need to be careful with pointers and what is allocated or not. I have rewritten your code but with the wrong solution. check comments.
#include <stdio.h>
#include <stdlib.h>
typedef struct emp_name {
/*
* now there you had just char*. this decares
* a pointer to some memory but no memory is allocated.
* if you were going with that approach you should initialize
* the struct and assign those values to something you malloc'ed().
* This version suffers from fixed size and a possible buffer overflow if
* you chose scanf to write the data in the buffer.
*/
char e_name[512];
char e_lastname[512];
/*
* try to follow conventions. your previous struct declarations
* were anonymous. if it caught an error you wouldn't know in which
* struct it would be. good practices here: link1 (bottom)
*/
} emp_name_t;
typedef struct emp {
emp_name_t emp;
int id;
} emp_t;
int main(int argc, char *argv[]) {
int i;
int cod=100;
emp job[3];
for (i=0;i<3;i++) {
/*
* check out this excelent post for a secure alternative:
* link2 (bottom)
*/
scanf("%s",&job[i].emp.e_lastname);
job[i].id=cod;
cod++;
}
for (i=0;i<3;i++) {
printf("%s",job[i].emp.e_lastname);
printf("%d\n",job[i].id);
}
return 0;
}
link1: openbsd style(9)
link2: disadvantages of scanf
Upvotes: 1
Reputation: 51423
You have three problem:
First you want to access:
job[i].name.e_lastname
not
job[i].emp.e_lastname
Second You should have:
scanf("%s",&job[i].name.e_lastname);
instead of
scanf("%s",job[i].name.e_lastname);
You do not pass &
since it is an array you are passing to the scanf function.
Third problem you should allocate memory to your char *e_lastname
and char *e_name
camps of the struct emp_name
.
Note that:
scanf
int scanf ( const char * format, ... );
Reads data from stdin and stores them according to the parameter format into the locations pointed by the additional arguments.
The additional arguments should point to already allocated objects of the type specified by their corresponding format specifier within the format string. (source)
So you want this:
int main(int argc, char *argv[])
{
int i;
int string_size = 10;
int cod=100;
emp job[3];
for (i=0;i<3;i++) // Allocate space for the string you will access.
{
job[i].name.e_name = malloc(sizeof(char)*string_size);
job[i].name.e_lastname = malloc(sizeof(char)*string_size);
}
for (i=0;i<3;i++)
{
scanf("%s",job[i].name.e_lastname);
job[i].id=cod;
cod++;
}
for (i=0;i<3;i++)
{
printf("%s",job[i].name.e_lastname);
printf("%d\n",job[i].id);
}
system("PAUSE");
return 0;
}
Consider the fact that using scanf is unsafe, because:
If you use the %s and %[ conversions improperly, then the number of characters read is limited only by where the next whitespace character appears. This almost cetainly means that invalid input could make your program crash, because input too long would overflow whatever buffer you have provided for it. No matter how long your buffer is, a user could always supply input that is longer. A well-written program reports invalid input with a comprehensible error message, not with a crash. (source)
Nevertheless, their are some workaround that you can do to use scanf (check them here)
Instead of scanf you can use fgets. fgets allows you to limit the data that will be placed in your buffer.
Upvotes: 1
Reputation: 3529
I see you have:
typedef struct
{
char* e_name;
char* e_lastname;
}emp_name;
typedef struct
{
emp_name name;
int id;
}emp;
emp job[3];
So what is .emp doing in the following line? Its not a member of any structure
job[i].emp.e_lastname
Upvotes: 0