踏出一步
2015年10月25日 星期日
2015年9月20日 星期日
[C筆記]系統呼叫exec()
作用:在程式中呼叫其他程式來運作,將目前行程交託給下一個程式,exec()將行程交託後,原程式將不再繼續運作。
sample code:
main.c
#include <unistd.h>//exec()的宣告
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>//errno的宣告
int main(int argc, char* argv[])
{
char *my_env[] ={"FOOD=coffee",NULL}; //環境變數name=value 並且用NULL告知程式最後項目
if(execle("./coffee","./coffee","donuts",NULL,my_env)==-1)//如果有找到coffee.exe就會跳去執行coffee.exe
{
fprintf(stderr,"cant run:%s\n",strerror(errno));//strerror(errno)為錯誤訊息種類
return -1;
}
return 0;
}
coffee.c
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char* argv[])
{
char *w = getenv("EXTRA");
if(!w)
w=getenv("FOOD"); //getenv("FOOD")抓取環境變數的值coffee
if(!w)
w = argv[argc -1];
char *c = getenv("EXTRA");
if(!c)
c= argv[argc -1];//讀取argv[1]
printf("%s with %s\n",c,w);
return 0;
}
補充:1
參照execle("./coffee","./coffee","donuts",NULL,my_env)
argc =2 argv[0] ="./coffee" argv[1]="donuts"
補充:2
exec種類
execl 接受引數串列
execv接受引數陣列
execl p 根據 路徑尋找程式
execl pe 使用環境字串的陣列
補充:3
errno 為錯誤編號
strerror(錯誤編號)回傳字串告知何種錯誤
補充:4
if(execle("./coffee","./coffee","donuts",NULL,my_env)==-1)
系統呼叫出問題時通常回傳-1 (但不總是-1)
執行結果
2015年8月30日 星期日
[C筆記]系統呼叫system()
前言: C語言幾乎仰賴著作業系統,system call 存在於核心,是C與OS溝通 的橋梁。
system()使用範例遇到的問題:
我嘗試了無數次cmd指令 echo %s %s >> reports.log
最後發現在我的%s裡面存在著\n換行字元導致我一直只有echo出前面的%s
剛好fgets這方法尾巴會加上換行字元 以及now()的回傳字串也有
sample code:
#include <stdlib.h>
#include <string.h>
#include <time.h>
char* now()
{
time_t t;
time(&t);
return asctime(localtime(&t));//結尾會自動加上\n導致echo指令出錯
}
int main()
{
char comment[80];
char cmd[120];
fgets(comment,80,stdin); //fgets結尾會自動加上\n導致echo指令出錯
if(comment[strlen(comment)-1] =='\n')
comment[strlen(comment)-1] ='\0';//將\n用字串結尾取代
char x[strlen(now())];
int i;
for(i=0;i<strlen(now());i++)
{
x[i]= *(now()+i); //*now存在記憶體的實字字串(不能修改)所以先丟到陣列進行修改
}
if(x[strlen(x)-4]=='\n')
x[strlen(x)-4]='\0';
sprintf(cmd,"echo %s %s >> reports.log",x,comment);
system(cmd);
return 0;
}
輸出結果
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!!
另外補充
當妳想確認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++;
}
}
-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;
}
執行結果:
訂閱:
文章 (Atom)