简体   繁体   English

C 字符串定义未知长度

[英]C string definition of unknown length

I need to store data (Of previously unknown format/size) inside a string for processing later (To be stored in an XML file)我需要将数据(以前未知的格式/大小)存储在一个字符串中以供稍后处理(存储在 XML 文件中)

How do I do this?我该怎么做呢?

As you can see, the code below will generate a segfault.如您所见,下面的代码将生成段错误。

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])));

}
[...]

In general, to "store data of an unknown size" in a C string, you have two choices:通常,要在 C 字符串中“存储未知大小的数据”,您有两种选择:

  1. Allocate a buffer large enough to hold any expected size (which means you would truncate the data if it exceeds that size), or分配一个足够大的缓冲区以容纳任何预期的大小(这意味着如果数据超过该大小,您将截断数据),或者

  2. Dynamically allocate a buffer (using malloc() ) that is large enough to hold the data.动态分配一个足够大的缓冲区(使用malloc() )来保存数据。 Don't forget to free() it, too.也不要忘记free()它。

Your code is using an uninitialised pointer output and that is why it is segfaulting.您的代码使用的是未初始化的指针output ,这就是它出现段错误的原因。 You will need to do one of the above.您将需要执行上述操作之一。

You are not allocating output and that is precisely why you are getting segmentation faults.您没有分配output ,这正是您遇到分段错误的原因。 As it is in the code provided, output has not been initialized.由于它在提供的代码中, output尚未初始化。 Your compiler should warn you of this.你的编译器应该警告你这一点。

If you know a safe maximum size, you can simply allocate it on the stack:如果您知道安全的最大大小,您可以简单地在堆栈上分配它:

char output[512];

...if the maximum size was 512 bytes. ...如果最大大小为 512 字节。 Otherwise, you can look at malloc to allocate memory off the heap.否则,您可以查看malloc以从堆中分配 memory。

If your platform has snprintf or similar (most do), then you want something like this:如果你的平台有 snprintf 或类似的(大多数都有),那么你想要这样的东西:

int n = snprintf( NULL, 0, "%s is %d", somestring, someinteger );
char * p = malloc( n + 1 );
sprintf( p, "%s is %d", somestring, someinteger );

The first call to snprintf returns how many chars would be needed to store the formatted output, but doesn't actually do any formatting.第一次调用snprintf返回需要多少字符来存储格式化的 output,但实际上并没有进行任何格式化。 Then you allocate the space needed and do the real formatting.然后分配所需的空间并进行真正的格式化。

In addition to pre-allocate a big enough buffer or to truncate the output to size:除了预先分配足够大的缓冲区或将 output 截断为大小:

  1. Pre-process the generation (no writes, just count the lengthes) and allocate a suitable buffer for the second (really write) pass预处理生成(不写入,只计算长度)并为第二次(真正写入)传递分配合适的缓冲区
  2. Write to 'unlimited' storage: a file写入“无限”存储:一个文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM