Layla
Layla

Reputation: 5446

printing data from a struct

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

Answers (3)

ramrunner
ramrunner

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

dreamcrash
dreamcrash

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

fersarr
fersarr

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

Related Questions