我需要在字符串中存储数据(以前未知的格式/大小)以便以后处理(存储在XML文件中)
我该怎么做?
如您所见,下面的代码将生成段错误。
char * type;
char * output;
for (i=0; i< 10; i++){
if(strcmp(GTK_OBJECT_TYPE_NAME(g_hash_table_lookup(widgetbuffer,allocate[i])), "GtkAdjustment") == 0){
type = "spin";
sprintf(output, "%f", gtk_adjustment_get_value(GTK_ADJUSTMENT(g_hash_table_lookup(widgetbuffer,allocate[i]))));
}else if(strcmp(GTK_OBJECT_TYPE_NAME(g_hash_table_lookup(widgetbuffer,allocate[i])), "GtkCheckButton") == 0){
type = "check";
sprintf(output, "%d", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g_hash_table_lookup(widgetbuffer,allocate[i]))));
}else if(strcmp(GTK_OBJECT_TYPE_NAME(g_hash_table_lookup(widgetbuffer,allocate[i])), "GSList") == 0){
type = "radio"; // Loop through grouped buttons and find active one
sprintf(output, "%d", g_slist_position(g_hash_table_lookup(widgetbuffer,allocate[i]),
g_slist_find_custom(g_hash_table_lookup(widgetbuffer,allocate[i]),
NULL, (GCompareFunc) searchRadio)));
}else if(strcmp(GTK_OBJECT_TYPE_NAME(g_hash_table_lookup(widgetbuffer,allocate[i])), "GtkComboBox") == 0){
type = "combo";
sprintf(output, "%d", gtk_combo_box_get_active(GTK_COMBO_BOX(g_hash_table_lookup(widgetbuffer,allocate[i]))));
}else if(strcmp(GTK_OBJECT_TYPE_NAME(g_hash_table_lookup(widgetbuffer,allocate[i])), "GtkEntry") == 0){
type = "entry";
output = (char *) gtk_entry_get_text(GTK_ENTRY(g_hash_table_lookup(widgetbuffer,allocate[i])));
}
[...]
答案 0 :(得分:4)
通常,要在C字符串中“存储未知大小的数据”,您有两种选择:
分配足够大的缓冲区以容纳任何预期的大小(这意味着如果超过该大小,您将截断数据),或者
动态分配一个足够大的缓冲区(使用malloc()
)来保存数据。不要忘记free()
它。
您的代码使用的是未初始化的指针output
,这就是为什么它是segfaulting。您需要执行以上操作之一。
答案 1 :(得分:2)
您没有分配output
,这正是您遇到分段错误的原因。与提供的代码一样,output
尚未初始化。您的编译器应该警告您。
如果你知道一个安全的最大大小,你可以简单地在堆栈上分配它:
char output[512];
...如果最大大小为512字节。否则,您可以查看malloc
以从堆中分配内存。
答案 2 :(得分:2)
如果你的平台有snprintf或类似的(大多数都有),那么你想要这样的东西:
int n = snprintf( NULL, 0, "%s is %d", somestring, someinteger );
char * p = malloc( n + 1 );
sprintf( p, "%s is %d", somestring, someinteger );
第一次调用snprintf
会返回存储格式化输出所需的字符数,但实际上并不进行任何格式化。然后分配所需的空间并进行真正的格式化。
答案 3 :(得分:0)
除了预先分配足够大的缓冲区或将输出截断为size: