<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      glib簡單記錄包括字符串,主循環(huán),回調(diào)函數(shù)和xml解析

      一、將最近用到的glib字符串功能整理了下直接用程序記錄比較好看懂

      #define MAX_LEN 100
      gchar * demo (char* msg, ...)
      {
          gchar * pcfgfile = NULL,* para = NULL;
          va_list argp;
          va_start(argp,msg);//msg其實(shí)指的是第一個參數(shù),這個函數(shù)是讓argp指向demo實(shí)參的棧底,參數(shù)是按從右往左的順序壓入棧的,argp不包含msg
          pcfgfile = g_strdup_vprintf("%s %s %s %d",argp);
          va_end(argp);
          return pcfgfile;
      }
      int main(void){
          gchar * pfilename = "houjiao";
          gchar * strdouble = "11.11";
          gchar * strint = "123456;8910";
          gchar *test_str = NULL,* hj = NULL;
          gint len = 0;
          gchar buff_str[MAX_LEN+1];
          guint64 imsi = 123456789;
          gdouble test_duble = 0.0;
          gchar **str_array = NULL;

          //----------------------------------------------------------一 ------------------------------------------------------------------------
          //下面的這些函數(shù)會返回一個新的字符串緩沖區(qū)的指針,所以你在使用完后必須要釋放它們。
          //--------------------------------------------------------------------------------------------------------------------------------------
          /*
          gchar *g_strdup(const gchar *str)
          復(fù)制str并返回它的一個拷貝。并非返回原來字符串的指針而是重新申請一塊內(nèi)存將其指針返回。*/
          hj = g_strdup(pfilename);
          test_str = g_strdup(hj);
          g_free(hj);
          hj = NULL;
          g_print("%s\n",test_str); //輸出good

          /*
          gchar *strnfill(gsize length, gchar *fill_char)
          創(chuàng)建一個長度為length并被fill_char填充的字符串。如果fill_char為0則創(chuàng)建一個空字符串 */
          test_str = g_strnfill(10,0);
          g_print("%s\n",test_str);
          g_free(test_str);
          test_str = NULL;


          /*
          gchar *g_strdup_printf(const gchar *format, ...)
          像sprintf()一樣格式化字符串和參數(shù)。但是,你沒必要像sprintf()一樣創(chuàng)建和指定一個緩沖區(qū),GLib將這些自動做了。適合用于字符串拼 */
          test_str = g_strdup_printf("%s_%u",pfilename,1);
          g_print("%s\n",test_str);

          /*測試g_strdup_vprintf的拼接功能 類似上面g_strdup_printf函數(shù)的功能*/
          test_str = demo("","hj","is","number",1);//輸出this is a demo!
          g_print("%s\n",test_str);
          g_free(test_str);
          test_str = NULL;

          /*
          gchar *g_strconcat(const gchar *string1, ..., NULL)
          它接受任意數(shù)量的string作為參數(shù),并返回它們的連接后的字符串。必須將NULL作為這個函數(shù)的最后一個參數(shù) */
          hj = g_strdup(pfilename);
          test_str = g_strconcat("   ",hj,":","good person",NULL);//輸出   houjiao:good person
          g_print("%s\n",test_str);
          g_free(test_str);
          test_str = NULL;


          //----------------------------------------------------------二 ------------------------------------------------------------------------
          //在下面的函數(shù)中,你應(yīng)該為返回的結(jié)果申請空間。GLib并不會返回一個拷貝給你。它們與C相對應(yīng)的函數(shù)非常像,參數(shù)要包含一個足夠大的緩沖區(qū)來進(jìn)行字符串處理。
          //--------------------------------------------------------------------------------------------------------------------------------------
          /*
          gchar *g_stpcpy(gchar *dest, const gchar *src)
          拷貝src到dest,包括最后的NULL字符。如果它執(zhí)行成功,會返回dest中結(jié)束符拷貝的指針。*/
          test_str = (gchar *)g_malloc0(strlen(hj));
          g_stpcpy(test_str,hj);//函數(shù)返回的是結(jié)束符拷貝的指針這里即返回空字符串
          g_print("%s\n",test_str);//輸出,good
          g_slice_free1(strlen(hj),test_str);
          test_str = NULL;

          /*
          gint g_snprintf(gchar *string, gulong n, const gchar *format, ...)
          你必須確保string有足夠大的空間。而且你必須要用n來指定這個緩沖區(qū)的大小。返回值是輸出字符串的長度,也有可能這個輸出字符串為了適應(yīng)緩沖區(qū)的大小而被截?cái)?*/
          len += g_snprintf(buff_str+len,MAX_LEN-len,"%d,%d,%d,%"G_GINT64_FORMAT"",1,2,3,imsi);
          g_print("%s\n",buff_str);//輸出1,2,3,123456789

          /*測試g_strchug刪除字符串開始的空格*/
          test_str = g_strconcat("   ",hj,":","good person     ",NULL);
          test_str = g_strchug(test_str);//輸出houjiao:good person     光標(biāo)在這
          g_print("%s\n",test_str);

          /*
          gchar *g_strchomp(gchar *string)
          將string結(jié)尾的空格都刪掉,返回string */
          test_str = g_strchomp(test_str);
          g_print("%s\n",test_str);//houjiao:good person
          g_free(test_str);
          test_str = NULL;

          /*
          gchar *g_strstrip(gchar *string)
          將string開頭和結(jié)尾的空白字符都刪掉,返回string。*/
          test_str = g_strconcat("   ",hj,":","good person     ",NULL);
          test_str = g_strstrip(test_str);
          g_print("%s\n",test_str);//輸出houjiao:good person

          /*
          gchar *g_strdelimit(gchar *string, const gchar *delimiters, gchar *new_delimiter)
          將string中的delimiters各個字符都替換為new_delimiter這一個字符 */
          test_str = g_strdelimit(test_str,"good",'a');
          g_print("%s\n",test_str);//haujiaa:aaaa persan
          g_free(test_str);
          test_str = NULL;

          //----------------------------------------------------------三、 ------------------------------------------------------------------------
          //在下面的函數(shù)中,除了g_ascii_dtostr()之外,都不改變它們的參數(shù)。
          //--------------------------------------------------------------------------------------------------------------------------------------
          
          /*
          gchar *g_strstr_len(const gchar *haystack, gssize haystack_len, const gchar *needle)
          在haystack中遍歷haystack_len長度,如果找到了needle字串,則返回這個位置的指針,如果沒有找到則返回NULL。*/
          test_str = g_strstr_len(pfilename,strlen(pfilename),"jia");
          g_print("%s\n",test_str);//輸出jiao
          test_str = NULL;

          /*  
          gchar *g_strrstr(const gchar *haystack, const gchar *needle)
          類似于g_strstr_len,這個函數(shù)將會從后面開始查找,但是它并沒有haystack_len參數(shù)。 */
          test_str = g_strrstr(pfilename,"jia");
          g_print("%s\n",test_str);//輸出jiao
          test_str = NULL;

          /*
          gchar *g_strrstr_len(gchar *haystack, gssize haystack_len, gchar *needle)
          與g_strrstr()相同,但是它只在前haystack_len個字符中查找,第二個參數(shù)是-1表示在整個字符串中找*/
          test_str = g_strrstr_len(pfilename,-1,"a");
          g_print("%s\n",test_str);
          test_str = g_strrstr_len(pfilename,5,"a");
          g_print("%s\n",test_str);//輸出(null)

          /*
          gdouble g_ascii_strtod(const gchar *nptr, gchar **endptr)
          將string轉(zhuǎn)為雙字長度的浮點(diǎn)數(shù)。如果你提供了一個有效的endptr指針地址,這個函數(shù)會將指針設(shè)置到string中被轉(zhuǎn)換的最后一個字符的位置*/
          test_duble = g_ascii_strtod(strdouble,NULL);
          g_print("%.2f\n",test_duble);//輸出11.11

          /*
          gchar **g_strsplit(const gchar *string, const gchar *delimiter, gint max_tokens)
          使用delimiter來將string切割成至多max_tokens個部分。返回值是新申請的一個字符串?dāng)?shù)組,用來保存被切割的這些部分。
          這個字符串?dāng)?shù)組必須由你自己釋放。 如果輸入字符串是空的,這個返回值也是一個空的數(shù)組。 該法不改變原string */
          str_array = g_strsplit(strint,";",3);
          g_print("%s,%s\n",str_array[0],str_array[1]);//123456,8910
          
          /*
          gchar *g_str_joinv(const gchar *separator, gchar **str_array)
          將字符串?dāng)?shù)組組合成單個字符串,并將這個新申請的字符串返回。如果separator不空,g_str_joinv()會在每個字符串之間添加上一個separator分隔符。*/
          test_str = g_strjoinv(",",str_array);
          g_print("%s\n",test_str);//123456,8910    
          g_strfreev(str_array);
          str_array = NULL;
          g_free(test_str);
          test_str = NULL;

          /*測試g_ascii_strtoll將字符串轉(zhuǎn)成對應(yīng)整形的功能第三個參數(shù)是指的幾進(jìn)制*/
          test_str =strchr(strint,';');
          len = (gint)g_ascii_strtoll(strint,NULL,10);
          g_print("%d\n",len);//輸出123456
          strint = test_str +1;
          len = (gint)g_ascii_strtoll(strint,NULL,10);
          g_print("%d\n",len);//輸出8910
          g_free(test_str);
          test_str = NULL;
          return TRUE;
      }
      二、glib的主循環(huán)功能主要是為了看看主循環(huán)的串行

      /*
      自定義的事件源是一個繼承 GSource 的結(jié)構(gòu)體,即自定義事件源的結(jié)構(gòu)體 的第一個成員是 GSource 結(jié)構(gòu)體, 其后便可放置程序所需數(shù)據(jù), 例如:*/
      typedef struct _MySource MySource;
      struct _MySource
      {
          GSource source;
          gchar text[256];
      };
      /*
      實(shí)現(xiàn)了事件源數(shù)據(jù)結(jié)構(gòu)的定義之后,還需要實(shí)現(xiàn)事件源所規(guī)定的接口,主要為 prepare, check, dispatch, finalize 等事件處理函數(shù)(回調(diào)函數(shù)),它們包含于 GSourceFuncs 結(jié)構(gòu)體中。
      將 GSourceFuncs 結(jié)構(gòu)以及事件源結(jié)構(gòu)的存儲空間寬度作為參數(shù)傳給 g_source_new 便可構(gòu)造一個新的事件源,繼而可使用 g_source_attach 函數(shù)將新的事件源添加到主循環(huán)上下文中
      */
      static gboolean prepare(GSource *source, gint *timeout)
      {
          *timeout = 0;

          return TRUE;
      }

      static gboolean check(GSource *source)
      {
          return TRUE;
      }

      static gboolean dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
      {
          int i = 0;
          MySource *mysource = (MySource *)source;

          for (;i<6;i++)
          {
              g_print("%s%d\n", mysource->text,i);
          }

          return TRUE;
      }
      /*
      g_main_loop_run 函數(shù)運(yùn)行時,會迭代訪問 GMainContext 的事件源列表,步驟大致如下:
      a. g_main_loop_run 通過調(diào)用事件源的 prepare 接口并判斷其返回值以確定各事件源是否作好準(zhǔn)備。如果各事件源的 prepare 接口的返回值為 TRUE,即表示該事件源已經(jīng)作好準(zhǔn)備,否則表示尚未做好準(zhǔn)備。顯然,上述程序所定義的事件源是已經(jīng)作好了準(zhǔn)備。
      b. 若某事件源尚未作好準(zhǔn)備 ,那么 g_main_loop 會在處理完那些已經(jīng)準(zhǔn)備好的事件后再次詢問該事件源是否作好準(zhǔn)備 ,這一過程是通過調(diào)用事件源的 check 接口而實(shí)現(xiàn)的,如果事件源依然未作好準(zhǔn)備,即 check 接口的返回 FALSE,那么 g_main_loop_run 會讓主事件循環(huán)進(jìn)入睡眠狀態(tài)。
      主事件循環(huán)的睡眠時間是步驟 a 中遍歷時間源時所統(tǒng)計(jì)的最小時間間隔 ,例如在 prepare 接口中可以像下面這樣設(shè)置時間間隔。到達(dá)一定時間后, g_main_loop_run 會喚醒主事件循環(huán),再次詢問。如此周而復(fù)始,直至事件源的 prepare 接口返回值為 TRUE。*/
      int main1(void)
      {
          GMainLoop *loop = g_main_loop_new(NULL, TRUE);
          GMainContext *context = g_main_loop_get_context(loop);
          GSourceFuncs source_funcs = {prepare, check, dispatch, NULL};
          GSource *source = g_source_new(&source_funcs, sizeof(MySource));

          g_sprintf(((MySource *)source)->text, "Hello world");

          g_timeout_add(100, timeout_func, loop);
          g_source_attach(source, context);
          g_source_unref(source);

          g_main_loop_run(loop);

          g_main_context_unref(context);
          g_main_loop_unref(loop);

          return 0;
      }
      /*
      該函數(shù)執(zhí)行結(jié)果是大致上可以看出來事件源是串行的即單線程
      */
      三、glib的xml解析功能順便使用簡單的回調(diào)函數(shù)

      //程序功能:使用回調(diào)函數(shù)的方式調(diào)用xml和txt兩種文件的讀取函數(shù)。
      xml文件里面的內(nèi)容如下
      <?xml version="1.0" encoding="UTF-8"?>
        <NM id="15009244480" name="houjiao">
            <title>name ege sex what emotion</title>
              <v>hq 24 female friend love</v>
              <v>ld 24 female friend love</v>
              <v>wj 25 female friend love</v>
              <v>wff 25 female friend love</v>
        </NM>
      txt文件里面內(nèi)容如下
      hq is 24 years older,and she is my friend.
      ld is 24 years older,and she is my friend.
      wj is 25 years older,and she is my friend.
      wff is 25 years older,and she is my friend.
      然后程序如下,注釋已經(jīng)很清晰了

      #include "glib.h"
      #include "string.h"
      #include "stdio.h"
      //定義函數(shù)指針即回調(diào)函數(shù)的類型
      typedef gboolean (*CallBackFileRead)(gchar *);
      typedef struct _FriendNode
      {
          gchar * myname;
          gchar * hername;
          gchar * what;
          gchar * emotion;
          guint8 ege;
          guint64 tel_id;
          gboolean txt_pasre_flag;
      }FriendNode;

      /*當(dāng)遇到元素開始時,將其屬性名全存到attribute_name數(shù)組中,對應(yīng)的屬性值存入value_cursor數(shù)組中,所以屬性名和屬性值是同時++然后就會取到下一個屬性直到取完*/
      static void start( GMarkupParseContext * context,
                        const gchar * element_name,
                        const gchar * * attribute_names,
                        const gchar * * attribute_values,
                        gpointer user_data,
                        GError * * error )
      {
          const gchar * * name_cursor = attribute_names;
          const gchar * * value_cursor = attribute_values;
          FriendNode * friend_node =(FriendNode *)user_data ;
          if (g_strcmp0(element_name,"v") == 0)
          {    
              friend_node->txt_pasre_flag = TRUE;        
          }
          else if (g_strcmp0(element_name,"NM") == 0)
          {
              while (*name_cursor)
              {
                  if (g_strcmp0(*name_cursor, "id") == 0)
                  {
                      friend_node->tel_id = (guint64)g_ascii_strtoull(*value_cursor,NULL,10);

                  }
                  else if (g_strcmp0(*name_cursor, "name") == 0)
                  {
                      friend_node->myname = g_strdup (*value_cursor);
                  }
                  name_cursor++;
                  value_cursor++;
              }
              g_print("My name is %s,my telphone num is %"G_GUINT64_FORMAT" \n",friend_node->myname,friend_node->tel_id);
          }
      }
      //一個元素結(jié)束時調(diào)用,一般可以在你想要取值的元素設(shè)置標(biāo)記。
      static void end( GMarkupParseContext * context,
                      const gchar * element_name,
                      gpointer user_data,
                      GError * * error )
      {
          FriendNode * friendnode = (FriendNode*)user_data;
          if (g_strcmp0(element_name,"v") == 0)
          {
              friendnode->txt_pasre_flag = FALSE;
          }
      }

      //一般xml里面要取得最重要的是內(nèi)容,因此按照內(nèi)容格式不同,拆分字符串的方式不同。
      static void text( GMarkupParseContext * context,
                       const gchar * text,
                       gsize text_len,
                       gpointer user_data,
                       GError * * error )
      {
          const gchar * s = text;
          gchar * ss = NULL;
          int i=0;    //列索引
          FriendNode * friendnode = (FriendNode *)user_data;

          if (friendnode->txt_pasre_flag)
          {
              while ((ss = strchr((gchar *)s,' ')) && i<=3)
              {
                  switch (i)
                  {
                  case 0:                
                      friendnode->hername = g_strndup(s,ss-s);
                      break;
                  case 1:
                      friendnode->ege =(gint8)g_ascii_strtoull(s,NULL,10);
                      break;
                  case 3:                
                      friendnode->what = g_strndup(s,ss-s);
                      break;

                  default:
                      break;
                  }
                  s = ss + 1;
                  i++;
              }
              if (i == 4)
              {
                  friendnode->emotion =g_strdup(s);
              }
              g_print("%s is %d years older,and she is my %s who I %s\n",friendnode->hername,friendnode->ege,friendnode->what,friendnode->emotion);
              g_free(friendnode->hername);
              g_free(friendnode->what);
              g_free(friendnode->emotion);
          }
      }
      //xml解析類回調(diào)函數(shù)的實(shí)現(xiàn)
      gboolean ReadXmlFile(gchar * filename){
          GMarkupParser gparser = {0};               //GMarkup解析器
          GMarkupParseContext *gparsecontext = NULL; //GMarkup解析上下文
          FriendNode friend_node = {0};
          char * buf;
          gsize length;
          /*創(chuàng)建解析器上下文第三個參數(shù)是用來傳給 GMarkupParser解析器函數(shù)即start,text和end里面用的 */
          gparsecontext = g_markup_parse_context_new(&gparser,(GMarkupParseFlags)0, &friend_node, NULL);

          if (gparsecontext == NULL)
          {
              return FALSE;
          }
          /*給gparser的函數(shù)指針賦值*/
          gparser.start_element = start;
          gparser.text = text;
          gparser.end_element =end;


          /* g_file_get_contents(const gchar *filename,gchar **contents,gsize *length,GError **error);
          是用于將文件的內(nèi)容讀入到一個buf中,length是用來存儲字符串長度的變量可設(shè)為null,讀取成功返回ture讀取失敗返回false和最后一個參數(shù) */
          if ((FALSE == g_file_get_contents(filename, &buf, &length,NULL)))
          {
              return FALSE;
          }


          /*開始解析buf里面的字符串,調(diào)用gparser的三個函數(shù),xml文件里面一個元素包括,元素名,屬性值和元素內(nèi)容,一個元素的start標(biāo)志為:<元素名[屬性]>,元素的end標(biāo)志為:</元素名> 包含在元素開始和元素結(jié)束之間的變是該元素的text*/
          if (g_markup_parse_context_parse(gparsecontext, buf, length, NULL) == FALSE)
          {
              g_message("load xml file failed!");
              g_free(buf);
              g_markup_parse_context_free(gparsecontext);
              gparsecontext = NULL;
              return FALSE;
          }
      }
      //csv解析類回調(diào)函數(shù)實(shí)現(xiàn)
      gboolean ReadTxtFile(gchar * filename){
          FILE * ftxt_file = NULL;
          gchar buf[100] = {'\0'};
          if (fopen_s(&ftxt_file,filename,"rb") != 0)
          {
              g_print("open file error");
              return FALSE;
          }
          //fgets遇到文件結(jié)束或讀取錯誤時返回null
          while(fgets(buf, 100, ftxt_file))
          {
             g_print("%s",buf);
          }
          fclose(ftxt_file);
          return TRUE;
      }

      void XmlTxtParseCallBack(gchar* filename, CallBackFileRead pFun)  //模擬API函數(shù)  
      {
          //回調(diào)解析文件類函數(shù)
          if (!pFun(filename))
          {
              g_print("parse error");
          }
      }
      //1.在main中的XmlTxtParseCallBack接口函數(shù)調(diào)用了回調(diào)函數(shù),當(dāng)然xml解析和txt解析的兩個函數(shù)可以像普通函數(shù)一樣被調(diào)用,但是當(dāng)它作為參賽傳遞給被調(diào)函數(shù)時就稱為回調(diào)函數(shù)了。
      //2.回調(diào)函數(shù)實(shí)際上就是在調(diào)用某個函數(shù)(通常是API函數(shù)時),將自己的一個函數(shù)(這個函數(shù)叫回調(diào)函數(shù))的地址作為參數(shù)傳遞給那個函數(shù),那個函數(shù)在需要的時候利用傳遞的地址調(diào)用回調(diào)函數(shù),這種模式很適合異步模塊之間的調(diào)用。
      //3.用計(jì)算機(jī)原理來說,回調(diào)函數(shù)就是一個中斷處理函數(shù),由系統(tǒng)在符合你設(shè)定條件時自動調(diào)用,你要做的只有三步,一聲明回調(diào)函數(shù)類型,二實(shí)現(xiàn)回調(diào)函數(shù),三,設(shè)置觸發(fā)條件(即把你的回調(diào)函數(shù)名轉(zhuǎn)化為函數(shù)指針作為參數(shù)用于調(diào)用)。
      int main()
      {
          gchar * filename = "F:\\test\\input\\hj.txt";
          if (g_str_has_suffix(filename,".xml"))
          {
              XmlTxtParseCallBack(filename,ReadXmlFile);
          }
          else if (g_str_has_suffix(filename,".txt"))
          {
              XmlTxtParseCallBack(filename,ReadTxtFile);
          }
          else
          {
              g_print("can't parse this file type");
          }
          return 0;

      }

      執(zhí)行結(jié)果是:

      當(dāng)filename是**hj.txt時,

      當(dāng)file那么是**hj.xml時,

      over,glib待續(xù)。。。

      posted @ 2014-08-22 13:06  風(fēng)猴藍(lán)魔  閱讀(3947)  評論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 亚洲一区二区精品动漫| 国产午夜亚洲精品不卡下载| 国产线播放免费人成视频播放| 美女胸18大禁视频网站| 强奷漂亮雪白丰满少妇av| 鲁丝片一区二区三区免费| 欧美成人免费全部| 成人亚洲狠狠一二三四区| 久久精品无码一区二区小草| 成人亚欧欧美激情在线观看| 高潮精品熟妇一区二区三区| 99久久国产成人免费网站| 丝袜人妖av在线一区二区| www国产亚洲精品久久网站| 亚洲av无码精品蜜桃| 乱中年女人伦av三区 | 福利一区二区在线观看| 龙陵县| 色悠久久网国产精品99| 国产精品中文字幕综合| 国产熟睡乱子伦视频在线播放| 国产精品一品二区三四区| 自拍亚洲一区欧美另类| 亚洲国产精品老熟女乱码| 亚洲精品成人网久久久久久| 国产成人精品国内自产色| 亚洲人成人网站色www| 国产成人毛片无码视频软件| 1024你懂的国产精品| 亚洲 自拍 另类 欧美 综合| 激情综合色综合啪啪开心| 蜜桃臀av一区二区三区| 强奷白丝美女在线观看| 无码日韩精品一区二区免费| 国产熟睡乱子伦视频在线播放| 久久蜜臀av一区三区| 亚洲中文字幕一二区日韩| 精品欧美一区二区三区久久久 | 好屌草这里只有精品| 中文字幕有码无码AV| 精品国产成人午夜福利|