C字符串定义未知长度

时间:2011-05-01 19:54:28

标签: c string casting

我需要在字符串中存储数据(以前未知的格式/大小)以便以后处理(存储在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])));

}
[...]

4 个答案:

答案 0 :(得分:4)

通常,要在C字符串中“存储未知大小的数据”,您有两种选择:

  1. 分配足够大的缓冲区以容纳任何预期的大小(这意味着如果超过该大小,您将截断数据),或者

  2. 动态分配一个足够大的缓冲区(使用malloc())来保存数据。不要忘记free()它。

  3. 您的代码使用的是未初始化的指针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:

  1. 预处理生成(没有写入,只计算长度)并为第二次(真正写入)传递分配合适的缓冲区
  2. 写入'无限'存储:文件