Question

I have to print some values stored in the struct to single char array , I am not getting an simple method to allocate a memory for a variable array values .

below snnipet of the code which I need to do

 struct types {

char *name;
char *address;
char * descrption;
};

int main ()
{

  int numberofUser = 10;

  struct types allUsers[numberofUser];

  //Assume here I filled all the user details by allocation memory.

  // now I need to print these values in the formated string like below


 char* outputString;

 int i ;
 for(i =0 ; i<numberofUser;i++)
 {
 sprintf(outputString,"<start>name=%s,add=%s,des=%s",allUsers[i].name,allUsers[i].address,allUsers[i].descrption);
 }
}

How to allocate memory for the output string which can hold all structure values

Was it helpful?

Solution

  1. Define the format string and store it in a variable of its own.

    char const* formatString = "<start>name=%s,add=%s,des=%s";
    
  2. Get the length of the format string.

    size_t formatStringLen = strlen(formatString);
    
  3. Get the lengths of the members of the struct.

    size_t nameLen = strlen(allUser[i].name);
    size_t addLen = strlen(allUser[i].address);
    size_t desLen = strlen(allUser[i].description);
    
  4. Allocate enough memory to hold the format string as well as the members of the struct.

    // This will be more than the exact space you need but certainly
    // not less than what you need and not too much more than what you
    // need.
    size_t totalLen = formatStringLen + nameLen + addLen + desLen;
    outputString = malloc(totalLen);
    
  5. Use sprintf

     sprintf(outputString, formatString,
             allUsers[i].name, allUsers[i].address, allUsers[i].descrption);
    

OTHER TIPS

You need to calculate length of strings involved and allocate that much memory to it. Something like

int len = 0;

len = strlen(allUsers[i].name) 
      + strlen(allUsers[i].address) 
      + strlen(allUsers[i].descrption);
len += strlen("<start>name=") 
     + strlen(",add=") 
     + strlen(",des=");
len ++ // for '\0'

outputString = malloc(sizeof(char) * len);

Note: this is for 1 record in allUsers as strings may change in other elements.

You should check for valid pointers and should free memory after used.

The members of your structure are pointers to characters, i.e. of type char * but you need a character array to store the strings. The size of the array must be one more than the maximum length the string can have to accommodate the terminating null byte which marks the end of the string. I suggest the following changes -

#include <stdio.h>
#include <string.h>

#define NAMELEN 20+1  // max length of name + 1
#define ADDRLEN 40+1  // max length of address + 1
#define DESCLEN 80+1  // max length of description + 1

struct types {
    char name[NAMELEN];
    char address[ADDRLEN];
    char descrption[DESCLEN];
};

int main(void) {
    int numberofUser = 10;
    struct types allUsers[numberofUser];

    // assign values to array elements        

    // format string for sprintf
    const char *fstr = "<start>name=%s,add=%s,des=%s";

    // strlen doesn't count the null byte. macros include null byte
    // so get space for 2 extra null bytes which is not needed.
    int outlen = strlen(fstr) + NAMELEN + ADDRLEN + DESCLEN - 2;

    // variable-length to store the output string
    char outputString[outlen];

    for(int i = 0; i < numberofUser; i++) {
        sprintf(outputString, "<start>name=%s,add=%s,des=%s",
                allUsers[i].name,
                allUsers[i].address,
                allUsers[i].descrption);

        // print the string
        printf("%s\n", outputString); 
    }
    return 0;
}

If your compiler supports C99 then it shall contain function snprintf. To allocate and set your string, you can use the following code:

char *outputString;
int  len;
outputString = NULL;
len = 0;
for(;;) {
    // this loop is executed only two times
    len = 1 + snprintf(outputString, len, "<start>name=%s,add=%s,des=%s",allUsers[i].name,allUsers[i].address,allUsers[i].descrption);
    if (outputString != NULL) break;                  // success
    outputString = realloc(outputString, len);
    if (outputString == NULL) break;                  // fail
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top