C Structure to String

11,400

As indicated, one efficient approach to determining the amount of space required is to make an initial call to snprintf with str & size specified as NULL and 0, respectively forcing snprintf to return the number of characters that would have been written had str & size provided sufficient space for the write. You can then use the number of characters returned by snprintf + 1 to dynamically allocate a buffer sufficient to hold the structure contents converted to string. For purposes of the example, the output format is simply a comma separated string of the airport structure values (generally avoid a leading capital of variable/struct names in C, not invalid, just a matter of traditional style).

The following is one approach to this problem. The struct2str function returns a dynamically allocated string containing the contents of the airport struct, if successful, otherwise it returns NULL. If you are converting an array of airport entries, you can easily pass the number of elements in the array and modify the function to return an array of pointers to string. Let me know if you have questions:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    char *gpsId;
    char *type;
    char *name;
    double latitude;
    double longitude;
    int elevationFeet;
    char *city;
    char *countryAbbrv;
} airport;

char *struct2str (airport ap);

int main (void) {

    /* declare structure and initialize values */
    airport a = { "GPS100151", "GPS/ILS/RVR/AWOS", "A.L. Mangham Regional", 31.58, 94.72, 354, "Nacogdoches", "US" };

    /* convert struct a to string (no name conflict with struct) */
    char *airport = struct2str (a);

    printf ("\n airport as a string:\n\n  '%s'\n\n", airport);

    /* free dynamically allocated memory */
    if (airport) free (airport);

    return 0;
}

/* convert contents of airport structure to a comma
   separated string of values. Returns pointer to 
   dynamically allocated string containing contents 
   of airport structure on success, otherwise NULL.
*/
char *struct2str (airport ap)
{
    /* get lenght of string required to hold struct values */
    size_t len = 0;
    len = snprintf (NULL, len, "%s,%s,%s,%lf,%lf,%d,%s,%s", ap.gpsId, ap.type, ap.name, ap.latitude,
                    ap.longitude, ap.elevationFeet, ap.city, ap.countryAbbrv);

    /* allocate/validate string to hold all values (+1 to null-terminate) */
    char *apstr = calloc (1, sizeof *apstr * len + 1);
    if (!apstr) {
        fprintf (stderr, "%s() error: virtual memory allocation failed.\n", __func__);
    }

    /* write/validate struct values to apstr */
    if (snprintf (apstr, len + 1, "%s,%s,%s,%lf,%lf,%d,%s,%s", ap.gpsId, ap.type, ap.name, ap.latitude,
                    ap.longitude, ap.elevationFeet, ap.city, ap.countryAbbrv) > len + 1)
    {
        fprintf (stderr, "%s() error: snprintf returned truncated result.\n", __func__);
        return NULL;
    }

    return apstr;
}

Output

$ ./bin/struct_to_str

 airport as a string:

  'GPS100151,GPS/ILS/RVR/AWOS,A.L. Mangham Regional,31.580000,94.720000,354,Nacogdoches,US'
Share:
11,400
AndyPet74
Author by

AndyPet74

I attend University of Nebraska Lincoln as a Computer Engineer undergraduate and when I am not in class or studying I am usually working for a small local company as an general IT associate and programmer. I have been really interested in computers for many years now and I am especially glad to be in college where I can focus my studies on things I really like, except Physics, I really don't enjoy physics too much but gotta get through it. :)

Updated on June 14, 2022

Comments

  • AndyPet74
    AndyPet74 about 2 years

    So I have a structure that looks like this:

    typedef struct {
    char *gpsId;
    char *type;
    char *name;
    double latitude;
    double longitude;
    int elevationFeet;
    char *city;
    char *countryAbbrv;
    } Airport;
    

    I also have a function and the prototype for that function looks like this:

    char * airportToString(const Airport *a);
    

    I need to do what the name of the function suggest, I need to convert the Airport structure passed to a string and then using the driver program it will print the returned character array. I know about sprintf and all those ways but I don't want to print from this function I need to print from the the main function. I have some code where it is just a series of strcat but it seems like it is the wrong way of doing things PLUS when it gets to latitude it would fail because you can't use strcat to put a double into a string. The other stipulation is that I have to allocate the string dynamically so I had a line for malloc that looks like:

    char * array = (char * ) malloc((sizeof(Airport) * 1) + 8);
    

    but I think that will also present more errors than it is worth, the + 8 is just for the spaces for formatting and a null terminator at the end, but if got around to converting the doubles or int to string and they were large it would exeed the array bounds and go out of bounds correct? What is the best way to accomplish this task what I need to do is:

    Constructs a new string that represents the given airport. The details of formatting can be anything, but it should be readable and provide a reasonable amount of details about the Airport structure. Moreover, the returned string should be dynamically allocated.