未知长度的 C 字符串定义

发布于 2024-11-04 06:25:25 字数 1553 浏览 0 评论 0原文

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

}
[...]

I need to store data (Of previously unknown format/size) inside a string for processing later (To be stored in an XML file)

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

}
[...]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

始于初秋 2024-11-11 06:25:25

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

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

  2. 动态分配缓冲区(使用 malloc() )足够大以容纳数据。不要忘记也free()它。

您的代码使用未初始化的指针output,这就是它出现段错误的原因。您需要执行上述操作之一。

In general, to "store data of an unknown size" in a C string, you have two choices:

  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. Don't forget to free() it, too.

Your code is using an uninitialised pointer output and that is why it is segfaulting. You will need to do one of the above.

情何以堪。 2024-11-11 06:25:25

如果您的平台有 snprintf 或类似的(大多数都有),那么您需要这样的东西:

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

第一次调用 snprintf 返回存储格式化输出需要多少个字符,但实际上并没有这样做任何格式。然后分配所需的空间并进行真正的格式化。

If your platform has snprintf or similar (most do), then you want something like this:

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. Then you allocate the space needed and do the real formatting.

用心笑 2024-11-11 06:25:25

您没有分配output,这正是您遇到分段错误的原因。正如所提供的代码中所示,output 尚未初始化。你的编译器应该警告你这一点。

如果您知道安全的最大大小,则可以简单地将其分配在堆栈上:

char output[512];

...如果最大大小为 512 字节。否则,您可以查看malloc来从堆上分配内存。

You are not allocating output and that is precisely why you are getting segmentation faults. As it is in the code provided, output has not been initialized. 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. Otherwise, you can look at malloc to allocate memory off the heap.

温馨耳语 2024-11-11 06:25:25

除了预先分配足够大的缓冲区或将输出截断到一定大小之外:

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

In addition to pre-allocate a big enough buffer or to truncate the output to size:

  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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文