2015年7月24日 星期五

[java筆記]連結mysql



sample code


 public void start(Stage stage) throws ClassNotFoundException, SQLException {
     
         Class.forName("com.mysql.jdbc.Driver"); //jdbc驅動先載入 要加入mysql-connector-java-5.1.15-bin.jar不然會出錯
         String url = "jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=Big5";//我的資料庫url
        try {
           conn = DriverManager.getConnection(url,"root","1234");//帳號密碼
        } catch (SQLException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);//例外處理
        }
        Statement stmt = null;
        try {
            stmt = conn.createStatement();
            ResultSet result = stmt.executeQuery("SELECT * FROM qq WHERE name LIKE '%aa%'"); //qq               是資料表名子 name是欄位
            while (result.next()) { // ResultSet 為"集合" 一定要配合迴圈使用!
            String Name = result.getString("name");//在這裡我找到了2筆一筆內容 aa 另一筆內容 bbaabb
           
             }
        } catch (SQLException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }finally {
        if (stmt != null) { stmt.close(); }//關閉  Statement
    }

    }

我的資料庫介紹


程式碼執行記錄

我利用中斷點來看每一圈收到的值

第一圈找到 aa!!

第二圈找到 bbaabb!!


另外補充
當妳想確認SQL語法是否正確
可以在http://localhost/phpMyAdmin/ 測試






結果呢(這代表法語法正確)
可以直接回上一頁複製語法
貼近去java 這行裡面
      ResultSet result = stmt.executeQuery("SELECT * FROM qq WHERE name LIKE '%aa%'");




2015年7月19日 星期日

[C筆記]靜態程式庫(共用.h檔與共用.o檔)

前言:之前有提過為了不寫出臃腫不堪的程式碼,我們應該講每個功能(方法)分散寫到不同的.c檔(利用.h檔來共用方法),這裡記錄該如何在gcc下將不同目錄的.h及.o連結到一起!


main.c檔案的位置


checksum.h檔案位置


encrypt.h檔案位置



checksum.o及encrypt.o的位置


main.c code


#include <stdio.h>
#include <stdlib.h>
#include "encrypt.h"
#include "checksum.h"

int main(int argc, char *argv[])
{
  char s[]="speak sumthing";
  encrypt(s);
  printf("encrypt is %s\n",s);
  printf("checksum is %i\n",checksum(s));
  
   encrypt(s);
  printf("encrypt is %s\n",s);
  printf("checksum is %i\n",checksum(s));

  return 0;
}

checksum.c code


#include "checksum.h"

int checksum(char *s)
{
    int sum =0;
    while(*s)
    {
      sum= sum +*s;
      s++;
      }
      return sum;
 }

encrypt.c code


#include "encrypt.h"

void encrypt(char *s)
{
     while(*s)
     {
              *s=*s^31;
              s++;
      }
     
 }


gcc指令 與 執行結果



-I 告知.h檔的位置(folder  folder2  2個位置都存在.h檔)
-o檔直接告知my_object_file/encrypt.o
                        my_object_file/checksum.o



將.o收集到收藏檔(.a檔)裡面

建立收藏檔指令 ar rcs libfilename.a  file1.o file2.o <----要收藏的.o檔

建立.a檔開頭一定要lib

執行gcc main.c -L . -lfilename -o try 

-L .  <---注意 當收藏檔放在自己的目錄下一定要用-L告知 .當下目錄的意思


此範例用.a檔實作:


題外話在linux底下gcc指令  有關路徑的話必須先加上/

例如-I /folder    -L/where

2015年7月11日 星期六

[C筆記]彈性可變式函式

前言:這裡想做一個有彈性函式,彈性的意思是我想要在函式輸入參數的部分,不想限制使用者輸入固定的參數數量,例如 printf("%i%i%i%i%i%i%i%i%i",1,2,3,4,5,6,7,8,9),這個常用的輸出方法不並沒有限制使用者只能輸出幾個參數。


提醒:
#include <stdarg.h> 使用裡面的
類別 va_list                   //記錄使用者輸入的所有參數
方法 va_start(ap,args) //告訴程式從哪個參數之後才開始抓
方法 va_arg(ap,int)      //拿回使用者的參數  並且必須告知使用者參數的類別方法va_end(ap)            //結束參數串列


sample code:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

void total(int args,char *x, ...)
{
     va_list ap;
     va_start(ap,x); //從x 參數之後才開始抓參數
     int i;
     for(i=0;i<args;i++)
     {
       printf("%i\n",va_arg(ap,int));                                        
     }
     va_end(ap);
}

int main(int argc, char *argv[])
{
  total(4,"after_char_*x",4,3,2,1);//不算"after_char_*x",只輸出4個參數

  system("PAUSE");   return 0;
}

輸出結果



2015年7月9日 星期四

[C筆記]函式指標陣列配合enum當陣列索引值

前言:函式本身就是指標,這裡利用宣告指標陣列來將函式放進陣列裡,利用迴圈將函式通通跑一遍(優點是程式碼看起來精簡,容易擴充其他函式)。

通常會先去判斷enum item
if(enum item ==??)

{  

 再決定要帶入哪一個函式   但是這樣寫未免太複雜

}

...

...

...

...

if(enum item ==??)

{   

每新增一個函式   就外加一段 if 寫下來造成程式的冗長,容易混亂!!

}

這裡利用下列方法改良! 

enum item{AFUNCTION,BFUNCTION,CFUNCTION,DFUNCTION,NEWFUNCTION};  

enum可當索引值AFUNCTION=0,BFUNCTION=1,CFUNCTION=2,DFUNCTION=3

response r[] ={{"chou", AFUNCTION},{"yi", BFUNCTION},{"ming", CFUNCTION},{"pig",DFUNCTION},{"new", NEWFUNCTION}}; 

function[r[i].type](r[i]);  //這行不變


smaple code:

#include <stdio.h>
#include <stdlib.h>
 enum item{AFUNCTION,BFUNCTION,CFUNCTION,DFUNCTION};
//enum 設定 symbol AFUNCTION=0,BFUNCTION=1,CFUNCTION=2,DFUNCTION=3
 typedef struct{
         char *name;
         enum item type;
         }response;
void afunction(response r)
 {
      printf("%s\n",r.name);
      }
       
 void bfunction(response r)
 {
      printf("%s\n",r.name);
      }
       
 void cfunction(response r)
 {
      printf("%s\n",r.name);
      }
       
 void dfunction(response r)
 {
      printf("%s\n",r.name);
      }
int main(int argc, char *argv[])
{
  response r[] ={{"chou",AFUNCTION},{"yi",BFUNCTION},{"ming",CFUNCTION},{"pig",DFUNCTION}};
  
  void (*function[])(response) ={afunction,bfunction,cfunction,dfunction};
//將函釋放入 函式指標陣列裡!
  int i;
  for(i=0;i<4;i++)
  {
   function[r[i].type](r[i]);  
                  } 
  system("PAUSE");
  return 0;
}

執行結果:

2015年7月5日 星期日

[C筆記]函式進階應用講解

前言:一般函式的用法函式(參數) 但是這裡式使用進階用法函式(函式)這種 方式在c函式庫裡常常看到例如qsort(void* array ,size_t array,size_t item, int (*compar) (const void*,const void*))。


提醒:c語言中,函式在宣告的時候就已經是指標位置了,所以我們不存在 Funtion *x 這種宣告,因為函式回傳值沒有固定的類別,帶入的參數也沒有。
???? aa ( ???????)
{
    return ?????????;
}


提醒2:如何建造函式的指標呢??
假設有一個函式  

int  i_am_a_function (int a, char* b)//函數宣告本身就是一個指標位置
{
..............................................
}

我想宣告一個指標取代這個函式


int (*replace) (int, char*);

replace =  i_am_a_function;

replace(2,"sucessful");  等同於  i_am_a_function(2,"sucessful");


qsort 函式(函式) sample code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare_scores(const void*,const void*);
int compare_str(const void* ,const void* );

int main(int argc, char *argv[])
{
  int scores [] ={543,323,32,554,11,3,112};
  qsort(scores,7,sizeof(int),compare_scores);
  int i ;
  for(i =0; i< sizeof(scores)/4;i++)
  {
          printf("%i\n",scores[i]);
          }
          
  char *name []={"chou","yi","ming","is","pig"}; 
  
  qsort(name,sizeof(name)/4,sizeof(char*),compare_str);
  
  for(i=0;i<sizeof(name)/4;i++)
  {
    printf("%s\n",name[i]);
                               } 
  return 0;
}

int compare_scores(const void* x,const void* y)
{
     int a = *(int*)x;
     int b = *(int*)y;
     
     return a-b;
    }

int compare_str(const void* stra ,const void* strb)
{
        char** a  =(char**)stra; //    補充 void* 型別轉回  (char*)* = 字串* 
        char** b  =(char**)strb;
        return strcmp(*a,*b);
    }

這邊char**不是字串陣列  
圖解



這是一個排序程式
輸出結果












2015年7月1日 星期三

[C筆記] 資料結構(Linklist)與動態記憶體Heap配置使用與釋放

前言:為了能夠動態配製記憶體,利用 malloc()來跟記憶體申請空間(HEAP),HEAP空間不像STACK空間會自己釋放掉,所以必須依靠free() 來釋放記憶體。




code sample:


#include <stdio.h>
#include <stdlib.h>
#include <string.h> // 為了使用strdup

typedef struct island//<-命名             island 資料結構為linklist
        {
         char *name;
         char *open;
         char *close;
         struct island *next ; //遞回結構不能取消"命名" 
        }island;//<-別名
     
 island* creat(char* name)
 {
         island *i = malloc(sizeof(island));
         i->name = strdup(name); //請憶體配置name複本空間
         i->open = "09:00";
         i->close = "17:00";
         i->next =  NULL;
         return i;
         }
 void display(island *start)
 {
      island *i = start;
      for(;i!=NULL;i=i->next)
      {
        printf("name:%s open:%s - %s\n", i->name,i->open,i->close);
                             }
 }


void release(island *start)
{
     island *i = start;
     island *next = NULL;
   
     for(;i!=NULL;i=next)
     {
        next = i->next;
        free(i->name);
        free(i);                  
        }
     }

int main(int argc, char *argv[])
{
  island *start =  NULL;
  island *i =  NULL;
  island *next = NULL;
  char name[80];
  int count =0;
  for(;scanf("%79[^,],[\n]\n",name)== 1;i = next)
  {
      next =creat(name);
      if(start == NULL)
         start = next;
      if(i != NULL)
         i->next = next;
  }
  display(start);
  release(start);
  return 0;
}


main解說: 每新增一坐島嶼,就必須動態向記憶體申請一塊Heap空間(因為不知道有幾座島所以無法是先宣告在stack空間裡),建立島嶼的方法中 island* creat(char* name),藍色的兩行都是會向記憶體申請heap。


為什麼要用到strdup呢??原因在於

island* creat(char* name) c語言中不管設定指標或者陣列帶入函式都是送記憶體位置過去(就是指標)

island* creat(char* name) == island* creat(char name[])

換句話說當我們程式碼如果寫這樣   i->name = strdup(name); 紅色部分去除


islandA = creat(name);//假設name內容為a

islandB = creat(name);//假設name內容為b

此時  islandA 與 islandB 中的name 都會被修改成"b" 因為2者name都是指標指向真實記憶體位置

所以用strdup()在記憶體中另行存一個空間(heap),當不需要使用時,當然也必須做釋放的動作。

一個好的工程師除了程式不寫的臃腫不堪外,應該對記憶體的使用在腦海中有相當程度的對應圖。

trip.txt


輸出結果