LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
123
返回列表 发新帖
楼主: kiron

用GTK+编写数据库应用程序的问题,请大家帮忙看看这段程序

[复制链接]
 楼主| 发表于 2004-10-3 20:56:03 | 显示全部楼层
最初由 jerboa 发表
如果要转码的话,用我以前编写的宏就行了。如下:
#define UTF8(str) g_locale_to_utf8(str,-1,NULL,NULL,NULL)                /*本地码与UTF8编码*/
#define UUTF8(str) g_locale_from_utf8(str,-1,NULL,NULL,NULL)                /*UTF8编码转本地编码*/


不是编码的问题:(

我使用GDB调试的时候出现下面的信息后,程序退出,但之前语句是能执行的,图形能出来,数据库也能执行,只是到最后的时候出现下面段错误:
Program received signal SIGSEGV, Segmentation fault.
0x4000c673 in _dl_fini () from /lib/ld-linux.so.2

请问众位兄弟,出现段错误的时候,有什么技巧来查找错误,我已经又看了一个晚上了,还是弄不好,实在没法了。
发表于 2004-10-4 09:26:14 | 显示全部楼层
报歉,因为大家看了你的程序,我没有仔细看前面的。
我看了一下,发现问题应该在这儿:

  if (mysql_init (mysql) == NULL) return 1;

  mysql = mysql_real_connect (mysql, hostname, username, password, database, 0, 0, 0);

  if (mysql == NULL) return 1;

  sprintf (query, "SELECT * FROM station WHERE province=\"广东省\"");

  if (query_mysql (query) == 0) return 1;
//-----------------------------------------------------
query_result = mysql_store_result(mysql);  //呵呵,你少了一步保存查询指针,也就是说,query_result没有被赋值,你用了野指针
//-----------------------------------------------------
  row = mysql_fetch_row (query_result);
 楼主| 发表于 2004-10-4 12:30:48 | 显示全部楼层
最初由 jerboa 发表
报歉,因为大家看了你的程序,我没有仔细看前面的。
我看了一下,发现问题应该在这儿:

  if (mysql_init (mysql) == NULL) return 1;

  mysql = mysql_real_connect (mysql, hostname, username, password, database, 0, 0, 0);

  if (mysql == NULL) return 1;

  sprintf (query, "SELECT * FROM station WHERE province=\"广东省\"");

  if (query_mysql (query) == 0) return 1;
//-----------------------------------------------------
query_result = mysql_store_result(mysql);  //呵呵,你少了一步保存查询指针,也就是说,query_result没有被赋值,你用了野指针
//-----------------------------------------------------
  row = mysql_fetch_row (query_result);


gint
query_mysql (gchar *query)
{
  gint success = 0;

  if (mysql_query (mysql, query) == 0)
    {
      query_result = mysql_store_result (mysql);
      success = 1;
    }

  return success;
}

非常遗憾,我在这个函数里已经保存了查询指针了,我是调用query_mysql函数之后把查询结果存在了query_result里的。

现在的问题是,程序可以查询数据库,在用gdb调试时,在程序中的语句运行完查询语句,并用row数组取得一条记录后,我设置了一个断点,在这个断点后查询了row数组的值,里面的值已经是数据库里的内容了,即是说明数据库查询成功了。

之后我再一步步往下执行程序,当执行完显示主窗口的程序后,出现了预料中的窗口:我打算把数据库中查得的第一条记录的第一列字符串当作标签label = gtk_label_new (row[0]);的字符串显示出来。
此时程序运行在gtk_main ();按退出键之后,程序就收到了
Program received signal SIGSEGV, Segmentation fault.
0x4000c673 in _dl_fini () from /lib/ld-linux.so.2
的错误。
程序中的图形如图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
发表于 2004-10-4 16:15:27 | 显示全部楼层
sorry!您的程序,无论如何,我拿出我曾经编过的程序给您一个参考,我想你改一改应该能应用到您现在的查询。说明:我用了glade开发工具,其余应该不难。
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

#include <bonobo.h>
#include <gnome.h>
#include <mysql.h>

#include "callbacks.h"
#include "interface.h"
#include "support.h"
#include "qs.h"

#define GLADE_HOOKUP_OBJECT(component,widget,name) \
  g_object_set_data_full (G_OBJECT (component), name, \
    gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)

#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
  g_object_set_data (G_OBJECT (component), name, widget)

GtkWidget* create_query_ok_d_window (void);
void call_d_query_ok_result(GtkWidget *clist);

GtkWidget*
create_query_ok_d_window (void)
{
  GtkWidget *query_ok_window;
  GtkWidget *vbox1;
  GtkWidget *scrolledwindow1;
  GtkWidget *clist1;
  GtkWidget *label1;
  GtkWidget *label2;
  GtkWidget *label3;
  GtkWidget *label4;
  GtkWidget *label5;
  GtkWidget *label6;
  GtkWidget *label7;

  query_ok_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_size_request (query_ok_window, 800, 600);
  gtk_window_set_title (GTK_WINDOW (query_ok_window), _("\346\237\245\350\257\242\345\267\262\345\217\221\351\200\201\346\225\260\346\215\256"));
  gtk_window_set_position (GTK_WINDOW (query_ok_window), GTK_WIN_POS_CENTER);
  gtk_window_set_default_size (GTK_WINDOW (query_ok_window), 800, 600);
  gtk_window_set_destroy_with_parent (GTK_WINDOW (query_ok_window), TRUE);

  vbox1 = gtk_vbox_new (FALSE, 0);
  gtk_widget_show (vbox1);
  gtk_container_add (GTK_CONTAINER (query_ok_window), vbox1);

  scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
  gtk_widget_show (scrolledwindow1);
  gtk_box_pack_start (GTK_BOX (vbox1), scrolledwindow1, TRUE, TRUE, 0);

  clist1 = gtk_clist_new (7);
  gtk_widget_show (clist1);
  gtk_container_add (GTK_CONTAINER (scrolledwindow1), clist1);
  gtk_container_set_border_width (GTK_CONTAINER (clist1), 1);
  GTK_WIDGET_UNSET_FLAGS (clist1, GTK_CAN_FOCUS);
  gtk_clist_set_column_width (GTK_CLIST (clist1), 0, 68);
  gtk_clist_set_column_width (GTK_CLIST (clist1), 1, 95);
  gtk_clist_set_column_width (GTK_CLIST (clist1), 2, 103);
  gtk_clist_set_column_width (GTK_CLIST (clist1), 3, 118);
  gtk_clist_set_column_width (GTK_CLIST (clist1), 4, 127);
  gtk_clist_set_column_width (GTK_CLIST (clist1), 5, 110);
  gtk_clist_set_column_width (GTK_CLIST (clist1), 6, 80);
  gtk_clist_set_selection_mode (GTK_CLIST (clist1), GTK_SELECTION_BROWSE);
  gtk_clist_column_titles_show (GTK_CLIST (clist1));

  label1 = gtk_label_new (_("\346\217\220\345\205\245\350\241\214\350\241\214\345\217\267"));
  gtk_widget_show (label1);
  gtk_clist_set_column_widget (GTK_CLIST (clist1), 0, label1);
  gtk_label_set_justify (GTK_LABEL (label1), GTK_JUSTIFY_LEFT);

  label2 = gtk_label_new (_("\346\224\266\346\254\276\344\272\272\345\270\220\345\217\267"));
  gtk_widget_show (label2);
  gtk_clist_set_column_widget (GTK_CLIST (clist1), 1, label2);
  gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT);

  label3 = gtk_label_new (_("\346\224\266\346\254\276\344\272\272\345\220\215\347\247\260"));
  gtk_widget_show (label3);
  gtk_clist_set_column_widget (GTK_CLIST (clist1), 2, label3);
  gtk_label_set_justify (GTK_LABEL (label3), GTK_JUSTIFY_LEFT);

  label4 = gtk_label_new (_("\344\273\230\346\254\276\344\272\272\345\270\220\345\217\267"));
  gtk_widget_show (label4);
  gtk_clist_set_column_widget (GTK_CLIST (clist1), 3, label4);
  gtk_label_set_justify (GTK_LABEL (label4), GTK_JUSTIFY_LEFT);

  label5 = gtk_label_new (_("\344\273\230\346\254\276\344\272\272\345\220\215\347\247\260"));
  gtk_widget_show (label5);
  gtk_clist_set_column_widget (GTK_CLIST (clist1), 4, label5);
  gtk_label_set_justify (GTK_LABEL (label5), GTK_JUSTIFY_LEFT);

  label6 = gtk_label_new (_("\351\207\221\351\242\235"));
  gtk_widget_show (label6);
  gtk_clist_set_column_widget (GTK_CLIST (clist1), 5, label6);
  gtk_label_set_justify (GTK_LABEL (label6), GTK_JUSTIFY_LEFT);

  label7 = gtk_label_new (_("\345\244\207\346\263\250"));
  gtk_widget_show (label7);
  gtk_clist_set_column_widget (GTK_CLIST (clist1), 6, label7);
  gtk_label_set_justify (GTK_LABEL (label7), GTK_JUSTIFY_LEFT);

  /* Store pointers to all widgets, for use by lookup_widget(). */
  GLADE_HOOKUP_OBJECT_NO_REF (query_ok_window, query_ok_window, "query_ok_window");
  GLADE_HOOKUP_OBJECT (query_ok_window, vbox1, "vbox1");
  GLADE_HOOKUP_OBJECT (query_ok_window, scrolledwindow1, "scrolledwindow1");
  GLADE_HOOKUP_OBJECT (query_ok_window, clist1, "clist1");
  GLADE_HOOKUP_OBJECT (query_ok_window, label1, "label1");
  GLADE_HOOKUP_OBJECT (query_ok_window, label2, "label2");
  GLADE_HOOKUP_OBJECT (query_ok_window, label3, "label3");
  GLADE_HOOKUP_OBJECT (query_ok_window, label4, "label4");
  GLADE_HOOKUP_OBJECT (query_ok_window, label5, "label5");
  GLADE_HOOKUP_OBJECT (query_ok_window, label6, "label6");
  GLADE_HOOKUP_OBJECT (query_ok_window, label7, "label7");
  call_d_query_ok_result(clist1);
  return query_ok_window;
}
void call_d_query_ok_result(GtkWidget *clist)
{
    MYSQL mysql;
    MYSQL_RES *result;
    MYSQL_ROW row;
    static gchar *text[7];
    if(!mysql_init(&mysql))
    {
       qs_message(_("\n   初始化数据库失败!  \n"));
       return ;
    }
    if(!mysql_real_connect(&mysql,QS_LOCAL_HOSTS, QS_LOCAL_USER, QS_LOCAL_PASSWORD, QS_LOCAL_DATABASE, 0, 0, 0))
    {
      qs_message(_("\n   连接清算数据库失败!  \n"));
      return ;      
    }
    if( mysql_query(&mysql,"select bankin_num,payee_num,payee_name,payor_num,payor_name,amount,remark from tc_ok_d_data") )
    {
       qs_message(_("\n  执行查询失败!  \n"));
       mysql_close(&mysql);
       return ;
    }
    else
    {
        result = mysql_store_result(&mysql);
        gtk_clist_clear(GTK_CLIST(clist));
        while(row = mysql_fetch_row(result))
        {
            if( row == 0 ) /*这时可能对方还没有录入数据*/
            {
               mysql_free_result(result);
               mysql_close(&mysql);
               return ;
            }
            text[0] = UTF8(row[0]);
            text[1] = UTF8(row[1]);
            text[2] = UTF8(row[2]);
            text[3] = UTF8(row[3]);
            text[4] = UTF8(row[4]);
            text[5] = UTF8(row[5]);
            text[6] = UTF8(row[6]);
            gtk_clist_append(GTK_CLIST(clist),text);
        }
        mysql_free_result(result);
    }
    mysql_close(&mysql);

    return ;
}
/*做为参考*/
发表于 2004-10-4 16:54:27 | 显示全部楼层
gint
query_mysql (gchar *query)
{
gint success = 0;

if (mysql_query (mysql, query) == 0)
{
query_result = mysql_store_result (mysql);
success = 1;
}

return success;
}
我又看了您提供的程序,我分析如下:
如果就你提供的程序如何,就这个判断,对错全部为返回。我感觉如果您需要帮助,应该提供修改后的源码。
 楼主| 发表于 2004-10-5 21:09:18 | 显示全部楼层

重新调整了程序结构,终于成功了

多谢jerboa兄的大力帮助!多谢前面兄弟们的帮助。

调整程序还是老生常谈的问题,实现一个单一功能的函数,不要把不相关的代码写在一块,像我在上面写的代码,把mysql相关的语句和GTK+的语句杂合在一块,可能在访问变量的时候两者出了问题,编译能通过,但无法成功执行。
我调整了程序结构,把mysql初始化,查询的语句写成一个函数,主函数主要安排图形,结构较清晰,程序就没有什么问题。

我把程序认真写了一遍,把错误处理也写上了,已经较完整了,现在贴出来,希望能对遇到像我一样问题的兄弟有所帮助。

  1. #include <stdio.h>
  2. #include <gtk/gtk.h>
  3. #include <mysql.h>

  4. /* End define */

  5. /* Print Eoor funtion */

  6. void out_message (gchar * message)
  7. {
  8.   printf ("%s\n",message);
  9. }

  10. /* End print error funtion */


  11. /* Start a query from database and show with clist */

  12. int
  13. query_mysql (GtkWidget *list)
  14. {
  15.   gint success = 0;
  16.   
  17.   MYSQL *mysql;
  18.   MYSQL_RES *result;
  19.   MYSQL_ROW row;

  20.   if ((mysql = mysql_init (NULL)) == NULL)
  21.     {
  22.       out_message("数据库初始化失败!");
  23.       return 1;
  24.     }

  25.   mysql = mysql_real_connect (mysql, "localhost", "root", "greatlinux", "station_system", 0, 0, 0);

  26.   if (mysql == NULL)
  27.     {
  28.       out_message("数据库连接失败!");
  29.       return 1;
  30.     }
  31.   
  32. if  (mysql_query (mysql, "SELECT * FROM station WHERE province="广东省"") != 0)
  33.    {
  34.      out_message ("数据库查询失败!");
  35.      return 1;
  36.    }

  37. result = mysql_store_result (mysql);

  38. while ((row = mysql_fetch_row(result)) != 0)
  39.    {
  40.      gtk_clist_append (GTK_CLIST (list), row);
  41.    }

  42. mysql_free_result (result);
  43. mysql_close (mysql);

  44. return 0;

  45. }

  46. /* End query funtion */


  47. /* window quit funtion */

  48. void
  49. window_quit()
  50. {
  51.   printf ("Program quit now!\n");
  52.   gtk_main_quit ();
  53. }

  54. /* End quit funtion */

  55. /* Main funtion */

  56. int
  57. main (gint argc, gchar *argv[])
  58. {
  59.   GtkWidget *window;
  60.   GtkWidget *button;
  61.   GtkWidget *box;
  62.   GtkWidget *label;
  63.   GtkWidget *clist;

  64.   gchar *title_list[2] = {"省份","站名"};
  65.   
  66.   gtk_set_locale ();
  67.   gtk_init (&argc, &argv);

  68.   label = gtk_label_new ("数据查询结果");
  69.   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  70.   button = gtk_button_new_with_label ("退出");
  71.   box = gtk_vbox_new (TRUE, 5);
  72.   clist = gtk_clist_new_with_titles (2, title_list);
  73.   gtk_clist_set_column_width (GTK_CLIST (clist), 0, 100);

  74.   gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
  75.   gtk_box_pack_start (GTK_BOX (box), clist, FALSE, FALSE, 0);
  76.   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);

  77.   gtk_window_set_default_size (GTK_WINDOW (window), 200, 100);
  78.   gtk_window_set_title (GTK_WINDOW (window), "数据库查询窗口");
  79.   gtk_container_add (GTK_CONTAINER (window),box);

  80.   query_mysql (clist);
  81.   gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (window_quit), NULL);

  82.   gtk_widget_show (label);
  83.   gtk_widget_show (clist);
  84.   gtk_widget_show (button);
  85.   gtk_widget_show (box);
  86.   gtk_widget_show (window);

  87.   gtk_main ();

  88.   return 0;

  89. }
复制代码


用下面的语句编译程序:
gcc -o modify modify.c -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient -lz `gtk-config --cflags --libs`


程序运行结果如下,按“退出”按钮退出:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表