2016-11-19 20 views
0

我无法从我拥有的文本文件中填充组合框。假设我有一个10行的文本文件(每行包含一个单词)。使用我的代码,组合框将最终有10行的最后一行。如何从文本文件填写组合框 - C

我的实际文本文件的格式如下:

2p1 23 blocA 
2p2 16 blocB 
2p3 19 blocB 

这里是我使用的初始代码:

GtkWidget *create_class_combo() 
    { 
     GList *glist = NULL; 
     GtkWidget *combo; 

     FILE *fp = NULL; 
     Class c; 

     combo = gtk_combo_new(); 

     fp = fopen ("lists/class.txt","r"); 

     while (fscanf(fp, "%s %s %s \n", c.name, c.children, c.location) != EOF) 
     { 
      glist = g_list_append (glist, c.name); 
     } 

     fclose(fp); 

     gtk_combo_set_popdown_strings (GTK_COMBO (combo), glist); 

     return combo; 
    } 

这是类结构:

typedef struct Class 
    { 
     char name[20]; 
     char children[10]; 
     char location[30]; 
    } Class; 

经过一番测试,事实证明,“g_list_append”会覆盖它添加的最后一个项目,如果你使用相同的变量作为第二个参数。

所以,我用了一串字符串。它没有工作。它显示我一个空的组合框。

我使用了一个只包含一个字符串的结构数组。它没有工作。它显示我一个空的组合框。

我用g_list_concat旁边的第二变量为Glist,同时初始化在每个“而”循环结束时的第一个。它没有工作。

我只是困惑。 你能帮我吗?

更新:我发现组合框的不同功能,并在代码中使用它们。它现在有效。

GtkWidget *create_class_combo() 
{ 
GtkWidget *combo; 

FILE *fp = NULL; 
Class c; 

combo = gtk_combo_box_text_new_with_entry(); 

fp = fopen ("lists/class.txt","r"); 

while (fscanf(fp, "%s %s %s \n", c.name, c.children, c.location) == 3) 
{ 
    gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), c.name); 
} 

fclose(fp); 

return combo; 
} 
+0

你'的fscanf()'是错误的。你应该检查'3'而不是'EOF'。它现在的方式可能导致未定义的行为。您还应该检查值是否正在读取,而不是仅附加到列表中。 –

+0

@iharob“fscanf()”工作正常。我测试了它,这就是我总是使用它的方式。我继续扫描,直到我打开EOF,确保我遍历了我的所有文件。这些值也被读取并正确存储到变量中。 您可以尝试制作“名称”字符串。给它一个价值。将它附加到glist上。然后给它另一个价值。将它再次附加到同一个列表中。该列表将显示为与您最后添加的值相同的两个项目。 – Elyes

+0

你总是使用它错误。阅读文档。您的代码容易出现未定义的行为。 –

回答

0
  1. 首先,你fscanf()调用返回匹配的数目和你不检查,它可以被返回0而不是EOF因为没有比赛,也文件的末尾WASN” t在前面的读取操作中已达到,因此您需要检查它是否返回3而不是EOF

    此外,您应该尝试防止缓冲区溢出。您可以使用长度修改为"%s"符和使用目标数组的长度 - 1

    最后,在每一行的中间值似乎是一个整数,所以您可以使用"%4s%d%6s"作为格式参数fscanf()和请记住,检查3而不是EOF

  2. 你应该如何在gtk+填充组合框读取。你可以使用GtkTreeModelGtkTreeIter来很容易地填充它,你做这件事的方式也会很清楚。

    另一个好处是,你会是什么您的组合框项保存数据,您可以使用多列,存储额外的数据,你会很容易地从模型中获取更多的控制。

这是如何做到这一点的例子,错误处理应该提高了很多

#include <gtk/gtk.h> 

typedef enum Columns { 
    Name, Children, Location, ColumnsCount 
} Columns; 

static GtkWidget * 
create_and_populate_combo_box() 
{ 
    GtkListStore *model; 
    GtkWidget *combo; 
    GtkTreeIter iter; 
    GtkCellRenderer *column; 
    char name[4]; 
    int children; 
    char location[6]; 
    FILE *file; 
    // Create a new list store 
    model = gtk_list_store_new(ColumnsCount, 
             G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING); 
    if (model == NULL) 
     return NULL; 
    // Create the combo box 
    combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model)); 
    if (combo == NULL) 
     return NULL; 
    // Create a cell renderer to render text only (this is a basic one) 
    column = gtk_cell_renderer_text_new(); 
    if (column == NULL) 
     return NULL; 
    // Install the cell renderer and set the text column 
    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), column, TRUE); 
    gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), 
                column, "text", Name, NULL); 
    // Read data from the file 
    file = fopen("data.dat", "r"); 
    if (file == NULL) 
     return NULL; 
    while (fscanf(file, "%4s%d%6s", name, &children, location) == 3) { 
     gtk_list_store_append(GTK_LIST_STORE(model), &iter); 
     gtk_list_store_set(GTK_LIST_STORE(model), &iter, 
         Name, name, Children, children, Location, location, -1); 
    } 
    fclose(file); 
    // Set the first value as active 
    gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); 
    return combo; 
} 

int 
main(int argc, char **argv) 
{ 
    GtkWidget *window; 
    GtkWidget *combo; 
    gtk_init(&argc, &argv); 

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
    if (window == NULL) 
     return -1; 
    g_signal_connect(G_OBJECT(window), "destroy", 
               G_CALLBACK(gtk_main_quit), NULL); 
    combo = create_and_populate_combo_box(); 
    if (combo == NULL) 
     return -1; 
    gtk_widget_set_size_request(window, 100, -1); 
    gtk_container_add(GTK_CONTAINER(window), combo); 
    gtk_widget_show_all(window); 
    gtk_main(); 
    return 0; 
} 
+0

我明白你对fscanf()的看法。我将以这种方式开始使用它。谢谢。 我会看看使用GtkTreeModel并回复你。 – Elyes

+0

非常感谢您的详细解答。这个解决方案提供了很多选项来定制我的组合框。我在查看了一下后也找到了另一个解决方案。我用它更新了我的第一篇文章。 – Elyes