C 结构到字符串
C Structure to String
所以我的结构如下所示:
typedef struct {
char *gpsId;
char *type;
char *name;
double latitude;
double longitude;
int elevationFeet;
char *city;
char *countryAbbrv;
} Airport;
我还有一个函数,该函数的原型如下所示:
char * airportToString(const Airport *a);
我需要执行函数名称建议的操作,我需要将传递的 Airport 结构转换为字符串,然后使用驱动程序打印返回的字符数组。我知道 sprintf 和所有这些方法,但我不想从这个函数打印,我需要从 main 函数打印。我有一些代码,它只是一系列 strcat 但它似乎是错误的做事方式加上当它到达纬度时它会失败,因为你不能使用 strcat 将双精度数放入字符串中。另一个规定是我必须动态分配字符串,所以我有一行 malloc 看起来像:
char * array = (char * ) malloc((sizeof(Airport) * 1) + 8);
但我认为这也会出现比其价值更多的错误,+ 8 仅用于格式化空格和末尾的空终止符,但如果绕过将双精度或 int 转换为字符串和它们很大,它会超出数组范围并超出范围,对吗?完成此任务的最佳方法是什么,我需要做的是:
构造一个表示给定机场的新字符串。格式化的细节可以是任何东西,但它应该是可读的并且提供合理的
有关机场结构的详细信息。此外,返回的字符串
应该是动态分配的。
如前所述,确定所需 space 数量的一种有效方法是对 snprintf
进行初始调用,并将 str
和 size
指定为 NULL
和 0
,分别迫使 snprintf
到 return 如果 str
和 size
提供足够的 space,本应写入的字符数] 为写。然后,您可以使用 snprintf + 1
编辑的 return 字符数来动态分配足以容纳转换为字符串的结构内容的缓冲区。出于示例的目的,输出格式只是 airport
结构值的逗号分隔字符串(在 C 中通常避免 variable/struct 名称的前导大写,不是无效的,只是传统样式的问题) .
以下是解决此问题的一种方法。 struct2str
函数 return 是一个动态分配的字符串,其中包含机场结构的内容,如果成功,否则它 return 是 NULL
。如果您要转换 airport
个条目的数组,您可以轻松地传递数组中元素的数量并将函数修改为 return 一个指向字符串的指针数组。如果您有任何问题,请告诉我:
#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;
}
输出
$ ./bin/struct_to_str
airport as a string:
'GPS100151,GPS/ILS/RVR/AWOS,A.L. Mangham Regional,31.580000,94.720000,354,Nacogdoches,US'
所以我的结构如下所示:
typedef struct {
char *gpsId;
char *type;
char *name;
double latitude;
double longitude;
int elevationFeet;
char *city;
char *countryAbbrv;
} Airport;
我还有一个函数,该函数的原型如下所示:
char * airportToString(const Airport *a);
我需要执行函数名称建议的操作,我需要将传递的 Airport 结构转换为字符串,然后使用驱动程序打印返回的字符数组。我知道 sprintf 和所有这些方法,但我不想从这个函数打印,我需要从 main 函数打印。我有一些代码,它只是一系列 strcat 但它似乎是错误的做事方式加上当它到达纬度时它会失败,因为你不能使用 strcat 将双精度数放入字符串中。另一个规定是我必须动态分配字符串,所以我有一行 malloc 看起来像:
char * array = (char * ) malloc((sizeof(Airport) * 1) + 8);
但我认为这也会出现比其价值更多的错误,+ 8 仅用于格式化空格和末尾的空终止符,但如果绕过将双精度或 int 转换为字符串和它们很大,它会超出数组范围并超出范围,对吗?完成此任务的最佳方法是什么,我需要做的是:
构造一个表示给定机场的新字符串。格式化的细节可以是任何东西,但它应该是可读的并且提供合理的 有关机场结构的详细信息。此外,返回的字符串 应该是动态分配的。
如前所述,确定所需 space 数量的一种有效方法是对 snprintf
进行初始调用,并将 str
和 size
指定为 NULL
和 0
,分别迫使 snprintf
到 return 如果 str
和 size
提供足够的 space,本应写入的字符数] 为写。然后,您可以使用 snprintf + 1
编辑的 return 字符数来动态分配足以容纳转换为字符串的结构内容的缓冲区。出于示例的目的,输出格式只是 airport
结构值的逗号分隔字符串(在 C 中通常避免 variable/struct 名称的前导大写,不是无效的,只是传统样式的问题) .
以下是解决此问题的一种方法。 struct2str
函数 return 是一个动态分配的字符串,其中包含机场结构的内容,如果成功,否则它 return 是 NULL
。如果您要转换 airport
个条目的数组,您可以轻松地传递数组中元素的数量并将函数修改为 return 一个指向字符串的指针数组。如果您有任何问题,请告诉我:
#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;
}
输出
$ ./bin/struct_to_str
airport as a string:
'GPS100151,GPS/ILS/RVR/AWOS,A.L. Mangham Regional,31.580000,94.720000,354,Nacogdoches,US'