我在将字符串保存为闪电时遇到了很多麻烦。当我添加一个新字符串时,当我使用" FOR"打印整个列表时,所有前面的元素都会消失。它只是出现在我添加的最后一个,在列表中的其他空格中只是垃圾,就像这样:
OUTPUT按下按钮15
guardo el elemento:"15"
numero: "15"
OUTPUT按下按钮11
guardo el elemento:"11"
numero: ""
numero: "11"
OUTPUT按下按钮10
guardo el elemento:"10"
numero: ""
numero: ""
numero: "10"
OUTPUT按下按钮6
guardo el elemento:"6"
numero: ""
numero: ""
numero: "0�"
numero: "6"
我的列表在下一个结构中声明
typedef struct widgets {
...
GList *LISTA;
}WIDGETS;
并在主
中初始化gint main(gint argc,gchar *argv[])
{
...
WIDGETS *boton;
// 1.- Inicializar el ambiente
gtk_init(&argc, &argv);
boton = malloc(sizeof(WIDGETS));
boton->tipojuego=1;
boton->numMov=0;
boton->bandera=2;
g_timeout_add(1000,tiempo,boton);
boton->LISTA=NULL;
...
}
保存和打印列表元素的功能是(" elementos"指向与boton相同):
void movimientos(GtkWidget *widget,gpointer info)
{
WIDGETS *elementos=(WIDGETS*)info;
gchar *str;
gpointer infor;
gint i;
//str=malloc(3*sizeof(char));
str=gtk_widget_get_name(widget);
g_print("guardo el elemento:\"%s\" \n",str);
elementos->LISTA=g_list_append(elementos->LISTA, str);
// g_print("Ya se guardo %s",(gchar *)g_list_last(elementos->LISTA)->data);
for(i=0;i<g_list_length(elementos->LISTA);i++)
{
infor=g_list_nth_data(elementos->LISTA,i);
str=(gchar *)infor;
g_print("\nnumero: \"%s\"",str);
}
}
答案 0 :(得分:1)
您不应该将malloc
与GLIB一起使用:使用g_new()
或g_new0()
。您还应首先初始化boton
结构,特别是考虑到您将其传递给其他功能;不要使用赋值和函数调用交错初始化。
主要问题是gtk_widget_get_name()
返回一个const字符串,因此如果窗口小部件消失,返回的字符串将包含垃圾。您需要连接到GtkWidget::destroy
信号并从列表中删除元素,或者您必须复制gtk_widget_get_name()
返回的字符串,然后再将其添加到列表中(然后记住释放列表的内容以及列表。
然后问题是你的循环列表是一个非常低效的循环GList的方法:
在每次迭代时询问列表的长度,这意味着每次迭代列表;然后你使用g_list_nth_data()
,它会迭代列表,直到它到达索引。一个双向链表是不是一个数组,但你使用的是前者,因为它是后者。迭代列表的正确方法是:
GList *l = elementos->LISTA;
for (l = list; l != NULL; l = l->next) {
const char *str = l->data;
// ...
}
作为C编程质量和风格的附注:不要混合小写(boton
,elementos
)和大写(WIDGETS
,{{1 }})以这种方式(坚持一个案例),并且你重新投入很多(LISTA
是gpointer
的typedef并由C隐式投射。