正如所指出的,一個有效的方法來確定的所需的空間量是使至snprintf
的初始呼叫指定爲NULL
str
& size
和0
,分別迫使snprintf
返回,將已經被寫入了的字符數str
& size
爲寫入提供了足夠的空間。然後您可以使用snprintf + 1
返回的字符數來動態分配足以容納轉換爲字符串的結構內容的緩衝區。對於這個例子來說,輸出格式僅僅是一個逗號分隔的字符串結構值(通常避免在C中的變量/結構名稱的前導大寫,無效,只是傳統風格)。
以下是解決此問題的一種方法。如果成功,struct2str
函數將返回一個動態分配的包含airport struct內容的字符串,否則返回NULL
。如果要轉換airport
條目的數組,則可以輕鬆地傳遞數組中的元素數,並修改該函數以返回指向字符串的指針數組。讓我知道如果您有任何疑問:
#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'
'的snprintf()'將返回會如果傳入的大小是無限的已打印的字符數。你可以在任何緩衝區上調用它以獲得正確的大小來動態分配你的字符串,然後再用你動態分配的緩衝區再次調用它來實際寫入它。沒有必要說「我知道'sprintf'和所有這些方法」 - 如果你知道它們,那麼使用它們,它們是正確的方法。 –
我認爲我腦子裏有什麼問題,sprintf會不會真的打印我合併的字符串是正確的?它會將參數放入第一個參數中,然後我需要打印是的?例如,如果我有: sprintf(str,「Test%f」,M_PI); 它會把測試3.14 .....進入str但不打印是嗎? – AndyPet74
是的,這是正確的,'sprintf'和'snprintf'的輸出會進入您作爲第一個參數傳遞的緩衝區。 – user3386109