顯示文章

這裡允許您檢視這個會員的所有文章。請注意, 您只能看見您有權限閱讀的文章。


主題 - stlee

頁: 1 [2]
31
肉腳版 / 月經題......utf-8的問題
« 於: 2007-05-14 19:51 »
不好意思,爬了半天文沒看到想要的@@!

就是在終端機模式下抓網頁下來時,如果有big5的可以被正常顯示

但遇到utf-8編碼的網頁則無法正常顯示,雖然不影響抓取網頁,但就是很討厭>"<

請問可以設定成big5及utf-8共存嗎???也就是不管抓啥資料下來都能看得到

非常感謝^^!

32
由於之前的討論已經從網頁怎麼取得完全不會到已經可以取到所要的目標網頁了^^!

在這過程非常感謝各位大大熱心的解答提點,現在對這個"程式殼"已經有點概念了

現在還有一些問題想請教及對殼的行為模式希望能提出一些觀點及做法看看還有哪一些不

妥的萬望指點一番

首先是經由這三個討論串開始的
網址解析問題:
http://phorum.study-area.org/viewtopic.php?t=45639
如何回應伺服器要求輸入帳號密碼:
http://phorum.study-area.org/viewtopic.php?t=45874
連續發出兩個以上的GET有不同嗎?
http://phorum.study-area.org/viewtopic.php?t=45964

再次感謝在這三個討論串裡面解答的各位先進前輩,謝謝^^!


現在"程式殼"的做法陳述如下:
在這幾天由於一直在解讀由封包擷取器 Ethereal 及 What Is Transferring 所截取

下來的封包後發現,當我要去取得一個網頁的資料時必須先去看看"我發出了哪一些資料"

給伺服器,當然這是以一般IE的正常動作去擷取下來的封包,在這些由我發出去給server

的封包中有滿多類似的地方,那就是如果是要去取得頁面時都會發一個GET封包

而在 Ethereal 內所看到的Hypertext Transfer Protocol項目下所顯示出來的東西

正是我要去照抄的部分,但因頁面的不同而有一些不太一樣但是都還差沒多少

格式大概都是這樣:
代碼: [選擇]

GET /.............. HTTP/1.1\r\n
Accept:..........................\r\n
Referer:.........................\r\n
Accept-Language:............\r\n
Accept-Encoding:.............\r\n
User-Agent:.....................\r\n
Host:...............................\r\n
Connection:......................\r\n  

這邊雖然是一些二維陣列的字串,但可以把他視為是"兩個參數",第一個參數就是第一行
GET/.............................HTTP/1.1那裡

第二個參數就是下面那些了,因為我只要把他串在一起成為一個一維陣列字串傳過去就可

以了,所以這兩個部分想用一個"存在檔案裡面的字串變數"作為函數的參數

大概像這樣子
代碼: [選擇]

(http://xxx.com.tw)
[001]
<getcode>GET /.............. HTTP/1.1\r\n<getend>
<svreqfoot>Accept:..........................\r\n
Referer:.........................\r\n
Accept-Language:............\r\n
Accept-Encoding:.............\r\n
User-Agent:.....................\r\n
Host:...............................\r\n
Connection:......................\r\n<svreqend>
[002]
<getcode>GET /.............. HTTP/1.1\r\n<getend>
<svreqfoot>Accept:..........................\r\n
Referer:.........................\r\n
Accept-Language:............\r\n
Accept-Encoding:.............\r\n
User-Agent:.....................\r\n
Host:...............................\r\n
Connection:......................\r\n<svreqend>

(http://yyyyyyy.com.tw)
[001]
<getcode>GET /.............. HTTP/1.1\r\n<getend>
<svreqfoot>Accept:..........................\r\n
Referer:.........................\r\n
Accept-Language:............\r\n
Accept-Encoding:.............\r\n
User-Agent:.....................\r\n
Host:...............................\r\n
Connection:......................\r\n<svreqend>
[002]
<getcode>GET /.............. HTTP/1.1\r\n<getend>
<svreqfoot>Accept:..........................\r\n
Referer:.........................\r\n
Accept-Language:............\r\n
Accept-Encoding:.............\r\n
User-Agent:.....................\r\n
Host:...............................\r\n
Connection:......................\r\n<svreqend>
[003]
<getcode>GET /.............. HTTP/1.1\r\n<getend>
<svreqfoot>Accept:..........................\r\n
Referer:.........................\r\n
Accept-Language:............\r\n
Accept-Encoding:.............\r\n
User-Agent:.....................\r\n
Host:...............................\r\n
Connection:......................\r\n<svreqend>

<getcode><getend><svreqfoot><svreqend>(http://xxx.com)這幾個是暫時想到的,當然目前

有疑慮的就是那些<>[]()符號的問題,如果有先進知道這樣可能會有問題的麻煩提點一下

當然程式還沒開始寫,先把一些可能的錯誤想起來放總是好的^^!

也就是說要把他變成一些標準步驟,只要先去分析以封包擷取器節取下來的封包看他怎

麼發出去,就依樣畫葫蘆的傳出去並接收直到取得目標網頁為止,如此一來就算對方網站怎麼改

我們都不用去改程式,只要把"正常連線"的封包擷取下來後抄到"設定檔"內而程式照著

"設定檔"一個步驟一個步驟的傳回去,接收,傳回去,接收,就取到我們想要的目標網頁了

當然這是依照curl官方網站的這一個範例
http://curl.haxx.se/lxr/source/docs/examples/getinmemory.c
所延伸出來的想法(因為有給他小改一下後實做發現步驟相同但不同的只有參數,所以認為可以這樣做)

這是修改過來的函數(還有要再加一些東西進去,所以參考一下吧)
http://phorum.study-area.org/viewtopic.php?p=231932#231932


謝謝大家,謝謝^^!

33
雜七雜八 / 腰痛>"<
« 於: 2007-05-10 17:09 »
這幾天眼睛一直盯著螢幕,身體也不自覺往前傾,一直保持這個姿勢有好幾個小時@@!

昨天起床時就覺得下腰部怪怪的>"<今天起床後發現更嚴重一點了

年過35真的越來越不耐操了.....要開始保養身體了

戒煙,喝白開水,聽說不錯,尤其一起床(刷牙,痾便便前)先喝一大杯白開水(喝到覺得肚子有點漲)效果更好

34
延續"如何回應伺服器要求輸入帳號密碼"的問題

現在遇到的情況是在分析發上去的封包時有連續2個以上的GET很像用修改的函數沒辦法處理這種狀況= =?

請問這和發出一個GET的要求頁面命令有不同嗎???

謝謝,感恩^^!

35
在已經取得網頁以後(不是以瀏覽器,而是以程式取得伺服器傳回來的資料)如果在

已經有帳號及密碼的狀況下,該如何回應伺服器(以程式傳回封包的方式)所要求的資料

當然了,在無帳號密碼的情況下屬駭客行為不在發問範圍內^^!

在第一次抓下來的大多是長這樣子

36
程式討論版 / 網址解析問題
« 於: 2007-04-21 18:32 »
請問如以下網址(本站網址)
phorum.study-area.org/index.php

當在程式中以
代碼: [選擇]

hp=gethostbyname("phorum.study-area.org");
mamcpy(&local_addr.sin_addr.s_addr,hp->h_addr,4);
in.s_addr=local_addr.sin_addr.s_addr;
printf("IP=%s\n",inet_ntoa(in));

可以顯示出其IP為203.68.102.2xx
(不知道對不對,不過用yahoo的倒是與ping出來的結果一樣)

現在的問題是當以gethostbyname("phorum.study-area.org/index.php");
時則出現:"程式記憶體區段錯誤"的訊息

所以想請問以C語言來說該如何能進一步取得網站上的資源以做進一步分析
或是以其他語言來說,是如何去取得網站上的資料的(其步驟為何)

ps.不是要拿來做壞事的,純粹是要抓資料下來分析用的

非常之感謝,感恩 :D

37
在Linux的文字模式下寫程式說實在的並不是個愉快的經驗:-?
尤其是中文的問題,一個字一個字還好但有時候遇到處理"半個字"時簡直很讓人受不了
究其原因,在昨天晚上收到的一封電郵中指出該問題(許功蓋問題)簡直宣告了無解>"<
挖哩咧~~~我都寫好了才跟我說這是歷史錯誤

算了,回到問題本身吧
http://kevinkao.idv.tw/mt/archives/2005/04/post_185/
文中指出了一個問題
代碼: [選擇]

大五碼錯在哪裡?
  錯在編碼時沒有把美國標準資訊交換碼 ASCII(American Standard Code for Information Interchange)的控制碼摒除在外,凡是唸過計算機概論的人都知道ASCII是以位元組(byte)為單位,又1 byte=8 bits,所以ASCII最多可以編2^8=256個字元,對於只有26個字母的英文語系國家來說已綽綽有餘,但對於有幾萬字的中文絕對不夠,因此必須用兩個byte來代表一個中文字,如"中"字的編碼即是"A4A4″。然而,BIG5碼設計時為了避免與ASCII衝突,每個中文字的第一個byte僅使用 ASCII裡的高字元(129-255),但在第二個byte卻用到了部分低字元(1-128),這正是BIG5碼在日後應用上造成極大不便的最大幫兇了。

當然啦,最好的辦法就是不用大五碼,不過這又有另一個問題
如果有一個字的編碼是[a由[及a這兩個字元所組合的,明眼人一看就知道問題出在哪裡
這種編法根本不可行,因為將會無法知道[a是一個雙位元的字還是如[apple]這樣一個
字串的其中的前兩個字

所以從ascii的127後開始編很像可行,也確實可行,不過可能當初編碼時沒考慮到一些跳
逸字元如\及|所代表的特殊意義(當初可能這些字元也沒啥意義)所以啦,現在問題出來了
其實之前在DOS下就遇到過顯示"功能"這個字串時出現亂碼的問題(看來沒人去從頭解
決過)當初解決的辦法當然是顯示"功\能"就OK啦

不過當從DOS轉檯到Linux後發現這個從127開始編碼的問題更大了,原因是Linux將
127以後的字元視為"不可視字元"所以如果我有將一個中文字分成兩個顏色顯示的需求
或在螢幕邊界剛好只能容納變個中文字時就會出大亂子了

去年在寫文字處理器就遇到這個大麻煩.....
我滿喜歡用方塊反白來選取要複製的區塊的當然要把他寫進去了,不過.....問題出來了
文字當然要能移動啦....一串中文字右移後問題也來了
更別說將游標移到中文字上面了---->那是兩個ascii字元
所以當遇到"不可視字元"的問題時簡直有點想放棄投入Linux
不過事後想想...問題是人解決的嘛既然他有這個問題何不就他問題所在去給他解決看看
就寫了下面這些函數啦

當然了,這些函數一定還有沒解決到及錯誤的地方,現在提供出來給有需要的人去使用
希望能對您有所幫助

代碼: [選擇]

/*判斷字串*s的第flag個字元是否為中文字(可分出是左或右位元)
是中文字的第1個(左)位元時傳回ISEUCL='L'(76)
是中文字的第2個(右)位元時傳回ISEUCR='R'(82)
不是中文字時傳回NOTEUC='A'(65)
此函數不可改成直接以isprint(*(s+flag));而必須從第0個位元找到第flag個位元否則
在遇到中英文穿插的字串時將無法判斷flag所在字元是左位元或右位元還是非可視字元

如果遇到的第一個字元*(s+0)是右位元則會被視為左位元且後面可能都無法分出來
*/
int lee_iseuc(char *s,int flag)
{
 
  int i,sn,code;
 
  sn=strlen(s);
  if(flag>sn || flag<0)
    return(ERROR);
 
  for(i=0;i<sn;i++)
  {    
  /*先遇到非可視字元為中文雙位元(左位元):127~255且不是ASCII控制字元0~31*/
    if(!isprint(*(s+i)) && !iscntrl(*(s+i)))
    {
      code=ISEUCL;/*ISEUCL='L'(76) 左位元*/
      if(i==flag)
        break;
      i+=1;/*令i加1即右移一個位元旗標值(右位元)*/
      code=ISEUCR;/*ISEUCR='R'(82) 右位元*/              
    }  
    else      
      code=NOTEUC;/*NOTEUC='.'*/  
    if(i==flag)
      break;      
  }  

/*
for(x=0,n=0;n<sn;x++,n++)      
  mvprintw(1,x,"%c",*(sc+n));
mvprintw(2,0,"sn=%d i=%d flag=%d s=%s..code=%d ",sn,i,flag,s,code);
refresh();
*/  
  return(code);
 
}


/*除錯專用,因為會配置一*sc可參考*s內容加以除錯
*/
int lee_iseucm(char *s,int flag)
{
  char *sc;
  int i,sn,code;
  int x,n;

  sn=strlen(s);
  if(flag>sn || flag<0)
    return(ERROR);

  sc=malloc(sn);
  for(n=0;n<sn;n++)      
    *(sc+n)='*';
 
  for(i=0;i<sn;i++)
  {    
  /*先遇到非可視字元為中文雙位元(左位元):127~255且不是ASCII控制字元0~31*/
    if(!isprint(*(s+i)) && !iscntrl(*(s+i)))
    {
      *(sc+i)=ISEUCL;/*ISEUCL='L'(76) 左位元*/
      if(i==flag)
        break;
      i+=1;/*令i加1即右移一個位元旗標值(右位元)*/
      *(sc+i)=ISEUCR;/*ISEUCR='R'(82) 右位元*/          
    }  
    else      
      *(sc+i)=NOTEUC;/*NOTEUC='A'(65)*/
 
    if(i==flag)          
      break;      
 
  }
  code=*(sc+i);/*此列如移到迴路內必須在兩個if(i==flag)下各有一行否則會有bug*/

/*
for(x=0,n=0;n<sn;x++,n++)      
  mvprintw(1,x,"%c",*(sc+n));
mvprintw(2,0,"sn=%d i=%d flag=%d s=%s..code=%d ",sn,i,flag,s,code);
refresh();
*/
 
  free(sc);
  return(code);
 
}

/*取得*str字串陣列內0~size字元的(中文)狀態設定到*spb暫存區
*/
void lee_iseucp(char *str,char *spb,int size)
{
  int i,ch;

  for(i=0;i<size;i++)
  {
    ch=*(str+i);
    /*先遇到非可視字元為中文雙位元(左位元):127~255*/    
    if(!isascii(*(str+i)))
    {
      *(spb+i)=ISEUCL;/*ISEUCL='L'(76) 左位元*/
      i+=1;/*令i加1即右移一個位元旗標值(右位元)*/
      if(i>=size)
        break;
      *(spb+i)=ISEUCR;/*ISEUCR='R'(82) 右位元*/
    }
    else if(iscntrl(*(str+i)))/*ASCII控制字元0~31*/
    {      
      if(*(str+i) == ISLF )/*換行字元*/
        *(spb+i)=ISLFCH;
      else if(*(str+i)== ISNULL)/*字串結束的'\0'字元*/
        *(spb+i)=ISNULL;
      else if(*(str+i) == ISTAB)/*Tab定位'\t'字元*/
        *(spb+i)=ISTABCH;
      else
        *(spb+i)='?';
    }
    else
      *(spb+i)=NOTEUC;/*NOTEUC='.'(46)*/
   
  }
}


代碼: [選擇]

/*記憶體區塊插入,*c的終點參數是endp(終點旗標)不是cn(字串長度)所以用cn傳入時須傳cn-1
*/
void lee_memcins(char *s,int ssz,int inssfootp,
                 char *c,int cfootp,int cendp)
{
  int sfootp,sendp,i,n,cn;
  char *buff;
  int sl,sr,cl,cr,slp,srp,clp,crp;

  /*越界檢查*/
  /*  if(sendp>=ssz ||/*區塊右邊界右越界*/
  /*     (sfootp==0 && cf==ISEUCR) ||/*區塊內左凸中文字元左越界*/
  /*     (sendp>=ssz-1 && ce==ISEUCL))/*區塊內右凸中文字元右越界*/
  /*    return;
  */

  slp=inssfootp;
  clp=cfootp;
  crp=cendp;
  sl=lee_iseuc(s,slp);
  cl=lee_iseuc(c,clp);
  cr=lee_iseuc(c,crp);
  srp=slp+(crp-clp)+1;

  if(cl==ISEUCR)/*要插入的區塊起點是中文字的右位元*/
  {
    clp-=1;/*令要插入的區塊起點左偏1位元*/
    slp-=1;
    sl=lee_iseuc(s,slp);
  }
  if(cr==ISEUCL)/*要插入的區塊終點是中文字的左位元*/
    crp+=1;/*令要插入的區塊終點右偏1位元*/
 
  cn=crp-clp+1;/*判斷完中文應偏值後取得實際要插入區塊的長度*/
/*
mvprintw(10,0,"cn=%d cr=%d *",cn,cr);
refresh();
*/
 
  /*將要插入區塊的內容覆製到暫存區這樣在要插入區塊與被插入區塊有重疊時不會重覆交
  但這僅限於同一維度內,如果是多維度區塊的插入在呼叫者函數內仍需先將其覆製到暫存區*/
  buff=(char *)malloc(cn+1);
  memset(buff,ISNULL,cn+1);
  lee_strszcpy(buff,c+clp,cn);
 
  if(sl==ISEUCR)/*被插入的區塊起點是中文字的右位元*/
    slp-=1;/*令被插入的區塊起點左偏1位元*/
   
  srp=slp+cn;/*被插入的區塊終點是被插入的區塊起點加實際要插入區塊的長度*/
  /*此迴路相當於將*s從slp處後推cn個位元*/
  for(i=ssz-1; i>=srp ;i--)/*i>=srp與i>=slp+cn意思一樣*/
    *(s+i)=*(s+(i-(srp-slp)));/**(s+(i-(srp-slp)))與*(s+(i-cn))意思一樣*/
  for(i=slp,n=0; n<cn ;i++,n++)/*此迴路將*c複製到*s的slp處*/
    *(s+i)=*(buff+n);

/*      
mvprintw(26,0,"ssz=%d buff=%s*",ssz,buff);
mvprintw(27,0,"sl=%d sr=%d cl=%d cr=%d slp=%d srp=%d clp=%d crp=%d cn=%d *",
               sl,sr,cl,cr,slp,srp,clp,crp,cn);
/**/
  free(buff);
  return;
}


/*記憶體區塊刪除,*s起點本身是中文的右位元時會有中文字串分析的錯誤
*/
int lee_memcdel(char *s,int ssz,int delsfootp,int den,int fill)
{
  int i,n,sl,sr;

/*mvprintw(24,0,"ssz=%d delsfootp=%d den=%d ",ssz,delsfootp,den);
*/  
  if(ssz<1 || den<1 || delsfootp+den > ssz )/*錯誤參數檢查*/
    return(0);

  sl=lee_iseuc(s,delsfootp);
  sr=lee_iseuc(s,delsfootp+(den-1));/*終點狀態*/
  if(sl==ISEUCR)/*刪除起點是中文雙位元的右位元*/
  {
    delsfootp-=1;/*自行向左偏移1個位元*/
    den+=1;/*自行偏移1位元後應刪位元數應多1位元*/
  }
  if(sr==ISEUCL)/*刪除終點是中文雙位元的左位元*/
    den+=1;
  for(i=delsfootp,n=delsfootp+den; i < ssz ;i++,n++)
    if(n<ssz)
      *(s+i)=*(s+n);
    else
      *(s+i)=fill;
/*mvprintw(25,0,"ssz=%d delsfootp=%d den=%d ",ssz,delsfootp,den);
*/
  return(den);
}

/*記憶體區塊替換,被替換區塊的中文狀態會和替換區塊比對,必要時會做偏移或覆蓋
*/
void lee_memcrep(char *s,int ssz,int repsfootp,
                 char *c,int cfootp,int cendp,int fill)
{
  int sfootp,sendp,i,n;
  int sl,sr,cl,cr,cn;
  char *buff;
 
  sfootp=repsfootp;
  sl=lee_iseuc(s,sfootp);
  cl=lee_iseuc(c,cfootp);
  cr=lee_iseuc(c,cendp);
  sendp=sfootp+(cendp-cfootp);
  /*越界檢查*/
  if(sendp>=ssz ||/*區塊右邊界右越界*/
    (sfootp==0 && cl==ISEUCR) ||/*區塊內左凸中文字元左越界*/
    (sendp>=ssz-1 && cr==ISEUCL))/*區塊內右凸中文字元右越界*/
    return;

  if(cl==ISEUCR)/*要替換的區塊起點是中文字的右位元*/
  {
    cfootp-=1;/*令要替換的區塊起點左偏1位元*/
    cl=lee_iseuc(c,cfootp);
    sfootp-=1;/*令被替換的區塊起點左偏1位元..edit的方形區塊中文左凸在覆製後可保持原狀*/
    sl=lee_iseuc(s,sfootp);
  }
  if(cr==ISEUCL)/*要替換的區塊終點是中文字的左位元*/
    cendp+=1;/*令要替換的區塊終點右偏1位元*/
  cn=cendp-cfootp+1;/*判斷完中文應偏值後取得實際要替換區塊的長度*/
  /*將要替換區塊的內容覆製到暫存區這樣在要替換區塊與被替換區塊在相同維度內有重疊時不會重覆交疊*/
  buff=malloc(cn+1);
  memset(buff,ISNULL,cn+1);
  lee_strszcpy(buff,c+cfootp,cn);
  if(sl==ISEUCR)/*被替換的區塊起點是中文字的右位元*/
    *(s+(sfootp-1))=fill;/*'a';/*消除該中文字的左位元*/
  sendp=sfootp+cn-1;/*被替換的區塊終點是起點加上要替換區塊的長度*/
  sr=lee_iseuc(s,sendp);
  if(sr==ISEUCL)/*被替換的區塊終點是中文字的左位元*/
    sendp+=1;

  for(i=sfootp,n=0; i<= sendp ;i++,n++)
    if(n<cn)
      *(s+i)=*(buff+n);
    else
      *(s+i)=fill;
/*mvprintw(26,0,"ssz=%d buff=%s*",ssz,buff);
mvprintw(27,0,"sl=%c-%d sr=%c-%d cl=%c-%d cr=%c-%d sfootp=%d sendp=%d cfootp=%d cendp=%d cn=%d*",
         sl,sl,sr,sr,cl,cl,cr,cr,sfootp,sendp,cfootp,cendp,cn);
*/
  free(buff);
  return;
}

38
剛剛看到的一篇文章
http://kevinkao.idv.tw/mt/archives/2005/04/post_185/

文章來源
http://forum.icst.org.tw/phpBB2/viewtopic.php?t=12101

心有悽悽焉,去年寫的一個文字處理器遇到類似"許功蓋"問題(但更嚴重點)

不過如果將字元拆開處理可以解決,因而寫了三個函數專門針對這個問題加以處理

明天貼上來吧,如果您有需要的話請不吝指教並回報問題喔....謝謝

是三個字串插入,增列,刪除的C語言函數

39
C/C++程式設計討論區 / C語言-子集合總數
« 於: 2007-04-11 15:07 »
一個集合內含元素如下{01,11,21,35,45,22,10,33,43,25}請求出子集合總數

要把這個程式寫出來其實有個公式可以運用,在以前曾經寫過一個34星計算的程式,其原理

相同,不過所謂34星只是求出上例集合中3個元素的子集合與4個元素的子集合而已,但其公

式可完全套用,所以下面將以本人比較熟悉的說法來加以說明

星=元素
連碰=子集合

首先來看一下這個公式,其實您只要到小書局買一本[港號連碰(彩住碰)總支數速見表]就有
這個公式了,不過有的寫得很複雜,有的寫的雖然簡單可是要把他套到程式裡面是要花一點
腦筋的,本人是屬於喜歡用簡單辦法花點腦筋套用的所以只說簡單辦法吧

先不管3星,來看4星及五星,有一個公式表是這樣的

四星
_4號互碰=4*3*2*1/24=1
_5號互碰=5*4*3*2/24=5
_6號互碰=6*5*4*3/24=15
_7號互碰=7*6*5*4/24=35
_8號互碰=8*7*6*5/24=70
_9號互碰=9*8*7*6/24=126
10號互碰=10*9*8*7/24=210
11號互碰=11*10*9*8/24=330
...........
...........

五星
_5號互碰=5*4*3*2*1/120=1
_6號互碰=6*5*4*3*2/120=6
_7號互碰=7*6*5*4*3/120=21
_8號互碰=8*7*6*5*4/120=56
_9號互碰=9*8*7*6*5/120=126
10號互碰=10*9*8*7*6/120=252
11號互碰=11*10*9*8*7/120=462
12號互碰=12*11*10*9*8/120=792
...........
...........

在這兩個表中發現一個公式,其中有幾項重點

1.不管多少號互碰她們最後都會去除一個值,而這個值是固定的,除非星數不同
2.乘法的第一個數字隨著n號互碰數增加而增加,其後的值遞減1
3.乘法所要相乘的個數隨星數不同,比如4星就是乘四個,5星乘五個
4.要去除的那個值剛好是第一列的乘積,四星的就是4*3*2*1=24,五星就是5*4*3*2*1=120

依上面四項重點我們可以得出六星的公式表(6星的公式表書上就沒了)
六星
_6號互碰=6*5*4*3*2*1/720(總碰數請自己拿計算機算一下吧)
_7號互碰=7*6*5*4*3*2/720
_8號互碰=8*7*6*5*4*3/720
_9號互碰=9*8*7*6*5*4/720
10號互碰=10*9*8*7*6*5/720
11號互碰=11*10*9*8*7*6/720
12號互碰=12*11*10*9*8*7/720
13號互碰=13*12*11*10*9*8/720
...........
...........

寫到這裡有經驗的程式師就應該已經知道怎麼把這個公式表簡化成為一行的公式了
所以本人就不雞婆啦--->依本討論區優良傳統->給釣竿不給魚吃--->就算幫你把魚釣起來了你也要把魚烤香香的請大家吃

不過要求總支數不可以用迴路寫,必須用遞迴,因為用迴路有個邏輯上的陷阱
(本人實做是用迴路,因為目標明確--->只求234星)

40
這個網址是YAM天空寬頻電視,其中有一個[ADSL頻寬測試]的選項
http://tv.yam.com/pay_moon.asp?c=3&s=31&ichannel=moon&PageUrl=MoonPlay&Moon=3&tar=_p_2&SegNo=SegNo&SegMenu=&pgmid=74_31_63870_155_EIB040006b55_%232007%2F03%2F31

小弟現在用的是中華電信光纖10m/2m的
換電腦(線路)前測出來的值都是4,500~8,000kbps左右

現在隨便測測都有13,000kbps以上,有一次用ie測更誇張測到270,000kbps以上(用ie都是100,000以上)...~~!

用火狐也都是在10,000kbps以上(沒ie那麼誇張)

之前在換線路時已經知道沒在用MOD時有額外的3m頻寬,但現在.....好像有點誇張了^^!

是賺到了嗎???心理有點小鹿亂撞呢^^!

42
一般來說程式是要拆成很多小的或特定功能的函數才能比較有生產力
可是當您日積月累後隨著函數不斷的增加,管理函數庫的機制也就更形重要了

好!我們平心靜氣(不要丟筆)拿張紙把下面的架構畫下來
代碼: [選擇]

  /  根目錄
  |
  |==[home] 家目錄
  |  |
  |  |==[stlee] 一般使用者目錄(名稱自取)
  |  |  |
  |  |  |==[leelib] 函數庫主目錄(名稱自取)
  |  |  |  |
  |  |  |  |--< libfile.a > .....
  |  |  |  |--<  libnet.a > 依格式加上與子目錄同名的函數庫,由go.sh自動編好
  |  |  |  |--<libstring.a> .....
  |  |  |  |--< lib***.a  > 編好的函數庫給gcc引用的,一定要lib****.a的格式
  |  |  |  |
  |  |  |  |==[file] 依功能取名的函數庫子目錄(名稱自取)
  |  |  |  |  |
  |  |  |  |  |--<go.sh   > 批次執行,純粹懶惰,因為每次執行./go.sh就編好函數庫了
  |  |  |  |  |--<makefile> 編譯連結命令,每增加一個.c檔時本檔裡面就要同步增加
  |  |  |  |  |--<fout.c  > 自己寫的不含main()的函數檔,裡面可以只有一個函數aa()
  |  |  |  |  |--<fmap.c  > 也可以有多個函數bb(),cc(),dd()...
  |  |  |  |  <*.c> 其他的函數檔
  |  |  |  |
  |  |  |  |==[net] 依功能取名的函數庫子目錄(名稱自取)
  |  |  |  |  |
  |  |  |  |  |--<go.sh   >
  |  |  |  |  |--<makefile>
  |  |  |  |  |--<getip.c >
  |  |  |  |  <*.c>
  |  |  |  |
  |  |  |  |==[string] 依功能取名的函數庫子目錄(名稱自取)
  |  |  |     |
  |  |  |     |--<go.sh   >
  |  |  |     |--<makefile>
  |  |  |     <*.c>
  |  |  |  
  |  |  |==[tmp] 程式都在這個目錄開發(名稱自取)
  |  |  |  |  
  |  |  |  |--<go.sh   > 與函數庫有點類似的批次處理
  |  |  |  |--<makefile> 編譯的命令列
  |  |  |  |--<svr.c   > 專案的主程式
  |  |  |  |--<bhf.c   > 專案的副程式
  |  |  |  <*.c>
  |  |  |  
  |  |  |==[include]自訂的含引檔都集中在這裡(名稱自取)  
  |  |  |  |  
  |  |  |  |--<state.h >主含引檔,所有函數原型都宣告在本檔,所有程式也都要含引本檔
  |  |  |  |--<file.h  > 與函數庫子目錄對應的含引檔名
  |  |  |  |--<net.h   > .....
  |  |  |  |--<string.h> .....
  |  |  |  <*.h>
  *  *  *

這是目前慣用的開發架構,並不會很複雜,但足以應付一般小型專案的需求了
有一些本人的習慣(說實在C語言想怎麼寫就怎麼寫沒有標準公式的)跟大家分享一下

1.函數庫主目錄,程式開發目錄,含引檔目錄,都給它分開
這三項工作都可以透過程式裡面或編譯指令指定路徑達到將一個專案連接在一起所以分
開管理,而這三種檔案類型在程式裡面都是會被拆得很嚴重的(尤其是函數)故將其分開
是本人慣用的一項習慣了(以前找怕了所以就自然養出來的習慣)

2.含引檔名取成和函數庫子目錄同樣的名稱,我也忘了為什麼要這樣(說過這是習慣嘛)

3.沒意外的話所有函數或主程式都只include一個.h檔,該.h檔將宣告所有的巨集替換
與所有的函數原型,這樣要找函數時會比較好找,而因將.h檔名稱取成和函數庫子目錄同
名稱所以也能幫助找或加入函數

4.因為架構成這樣了所以很自然而然的在寫函數的時候會考慮到通用性的問題,您不會
花好幾天只寫某個功能專用的函數吧(乾脆寫成通用功能),如果是這樣直接寫到主程式裡
面跑得還比較快不用拆出來了(重複出現的是一定要拆的啦)

5.各目錄下還可再細分子目錄,而三個主要工作目錄(函數庫leelib,程式開發tmp,含引檔include)
這樣分純粹只是其檔案型態的關係,如果遇到大一點的案子,就這三個目錄下分下去就好
了,另外分太多反而讓人眼花撩亂

===============================================
其函數庫目錄與主程式目錄下都有兩個檔案go.sh及makefile
將要下給gcc的編譯指令都放在makefile而go.sh只是做檔案批次處理的,函數庫與
主程式的有點不一樣而函數庫各子目錄下都有一組go.sh及makefile

這是函數庫子目錄下的go.sh
代碼: [選擇]
rm *.o
rm *.a
rm /home/stlee/leelib/libxxx.a
make
cp *.a /home/stlee/leelib

要先移除*.o及*.a是因為make並不會覆蓋舊的(要下參數,懶得查),所以手動將它移除
rm /home/stlee/leelib/libxxx.a是將上一層目錄的函數庫移除後由make在本目錄
編一個新的函數庫(函數庫名稱在makefile指定)後cp *.a /home/stlee/leelib 將編
好的函數庫複製到上層,放在這層也可以不過寫主程式的編譯指令就很煩惱了,所以還是
移到上層吧

再來是函數庫子目錄下的makefile裡面有幾個地方要注意的
代碼: [選擇]
LIB=libxxx.a

$(LIB):\
$(LIB)(aaa.o)\
$(LIB)(bbb.o)

aaa.o:aaa.c
########gcc -c aaa.c
bbb.o:bbb.c
########gcc -c bbb.c

分成三個部份,已將其分列處理

LIB=libxxx.a這就是指定該函數庫的名稱了,函數名稱請注意兩項規則1.前面3個字必須是lib  2.後面必須是.a
這兩個規則是gcc訂的,所以不要問我為什麼

$(LIB):\
$(LIB)(aaa.o)\
$(LIB)(bbb.o)
這幾個本來應該是"一列指令"但當.c檔越來越多時用過vi的人就知道了本人不再多說
因為原本是一列的所以要分成多列時必須在後面都加上一個\號以連結成一列最後一列請不要加\號

aaa.o:aaa.c
########gcc -c aaa.c
bbb.o:bbb.c
########gcc -c bbb.c
請注意aaa.o:aaa.c表示要以'aaa.c'編譯出'aaa.o'所以您可取為a001.o但不建議這
麼幹因為還必須對應到$(LIB)(aaa.o)這個命令所以都給他與aaa.c相同名稱吧
編譯指令將在緊接著的下一列
gcc -c aaa.c是上一列的編譯指令表示要將aaa.c交由gcc編譯
########gcc -c aaa.c的########是一個Tab請勿照著打
請將########的部分刪除後按TAB鍵可輸入一個Tab


所有函數庫子目錄下的go.sh都一樣所以各複製一份就好了
makefile的架構也都一模一樣所以也複製過去改一改就可以了
以後要編譯該子目錄下的函數庫時只要執行./go.sh就可以了,而當有新加入的函數時
1.如果加在原*.c裡面makefile不用管他,執行./go.sh就好了
2.增加*.c檔時makefile裡面的第2.3部分都要各加一組,同樣複製一下改一改就ok了

以上就是函數庫的部份,比較要注意的是makefile的\號有沒有多或少,Tab看起來和八
個空白一樣所以須逐列確認及*.o*.c的名稱是否有對應,我比較常發生*.o沒對應*.c
導致make錯誤訊息或gcc找不到函數,所以請記住一次就是改三個的原則就對了(請愛用複製功能,可以偷懶又不會打錯字)

===============================================

先說一下/home/stlee/include下面的.h檔吧

在這裡面有一個檔案是宣告所有函數庫裡面函數原型的.h檔名為state.h底下有個連結
http://phorum.study-area.org/viewtopic.php?p=220962#220962
就是長這樣子的,除了函數有個別需要含引標準函數的<***.h>外一定都有含引這個.h檔
#include "/home/stlee/include/state.h"這樣一來除了可以叫用自己開發的函數外
還可以避免相同名稱的重複,所以函數原型一定要宣告
怎麼宣告--->將.c擋裡面函數開頭的宣告複製過去後面加個;號再補點說明就好啦
而且通通集中管理也比較好找(以前發生過有個字串排列函數寫了五個不同名稱相同作用
的函數擺在3個不同的.h檔裡面)

===============================================
再來就是主程式下面的go.sh了
代碼: [選擇]
rm *.o
rm go
make
gdb go

其實都差不多,只是最後一列本人習慣在gdb除錯所以也可以直接go啦

然後是主程式下面的makefile也滿簡單的,只是編譯指令,但做到makefile裡可一次編
譯其他的副程式所以不放在go.sh裡面了
代碼: [選擇]
go:yyy.o
########gcc -L/home/stlee/leelib -D_REENTRANT -g -o go yyy.c -lxxx

比較要說明的是-lxxx就是在函數庫子目錄下編譯到函數庫主目錄下的各libxxx.a了
比如有三個為lib001.a,lib002.a,lib003.a這時要送給gcc時的參數就要下成
gcc -L/home/stlee/leelib -D_REENTRANT -g -o go yyy.c -l001 -l002 -l003
-lxxx 的 l 是 L 的小寫,後面的.a不用寫
-L/home/stlee/leelib則指向函數庫所在的目錄所以路徑千萬不要設錯
現在應該知道為什麼要將函數庫子目錄下的*.a通通搬到上一層了吧(否則命令會牽很長)
同樣的########也將其換成Tab吧
-D_REENTRANT忘記是做啥用的了,應該是不必要的,可以刪掉(有問題再補回來吧)

其實其他地方做好再開發主程式時可以比較專注在專案功能的開發上所以這裡變得比較
簡單了(程式的開發)

===============================================
在其他程式內如何使用函數庫呢

#include "/home/stlee/include/state.h"
main()
{
.....
aaa()
.....
bbb()
.....
}

就醬...aaa(),bbb()是在函數庫子目錄下寫好的函數(已將函數編進編進函數庫)
只有include一個state.h(將有宣告其原型的.h檔include進來)
在程式開發那個目錄下的makefile裡面加入有aaa(),bbb()的.a檔為參數-lxx -lyy(在命令內讓gcc找得到您的函數)

當然這只是一個模型,前面也說過C語言想怎麼寫就怎麼寫沒有標準公式的
所以只是將本人開發平台提出供有想用C語言在Linux寫點東西的同好分享一下的啦 :D

===============================================
開發新的函數,其實不一定都要跑到函數庫目錄下開發耶,我都是這樣做的
代碼: [選擇]
#include "xxx.h"

abc();

main()
{
  .....
  abc();
  .....
}

abc()
{
  .....
  .....
}

在main()裡面將abc()開發好後將abc()整個搬走到其他的*.c或開一個abc.c都可以
(新開abc.c要動到函數庫子目錄下的makefile)而且這樣一來主程式也比較清爽
函數開發時可以將函數原型宣告在main()上面,或宣告到xxx.h這就看個人囉!

43
請先看一下原碼
在printf("222 接收到使用者的連線要求 fd=%d\n",client_sockfd);
那幾行是目前知道的一個server端漏洞所在
而printf("444 伺服器已取得使用者傳來的字串=%c fd=%d \n",ch,fd);的區段因已可接收到
client端傳來的資料所以在這裡是能掌控範圍內
但步驟222的地方應該就是接收到封包的地方,以惡意侵入角度來說應該就是從這裡侵入才是
所以想用一個"乾淨封包"比對"連線進來的封包"的方式阻絕惡意入侵
在步驟444下面有一個IP迴避機制,因目前是測試階段所以擺在那裡與本主題無關

代碼: [選擇]

int main()
{
  /*socket所需的宣告*/
  int server_sockfd,client_sockfd;
  int server_len,client_len;
  struct sockaddr_in server_address;
  struct sockaddr_in client_address;

  /*執行緒所需的宣告*/
  int res;
  pthread_t a_thread;
  void *thread_result;

  /**/
  char *ipstr;
  int ethmax;
  int ethfoot,ethend;

  char ch;
  int fd;
  int nread;
  int result;
  fd_set readfds,testfds;

  int i,n,k;

  char *c;

  ipstr=(char *)malloc(IPSMAX*IPSLEN);
  ethmax=IPSMAX;
  ethfoot=0;
  ethend=0+(IPSMAX-1);
  /*取得浮動IP*/
  for(i=0;i<ethmax;i++)
    memset(ipstr+(i*IPSLEN),'\0',IPSLEN);
/*  lee_newip(ETHSTR,ethfoot,ethend,ipstr,IPSLEN);/*一次取得全部的IP*/


/**/lee_getaddrl("ppp0",ipstr+(0*IPSLEN),SG_IP);
/**/lee_getaddrl("ppp1",ipstr+(1*IPSLEN),SG_IP);


  /*AF_INET:使用IPv4網路協定;SOCK_STREAM=提供雙向連續且可信賴的資料流,即TCP*/
  server_sockfd = socket(AF_INET,SOCK_STREAM,0);

  /*填寫sockaddr_in結構
  sin_family      為呼叫 socket()時的domain引數,即為AF_xxx的值
  sin_addr.s_addr 為IP位址
  sin_port        為使用的port編號
  */
  server_address.sin_family = AF_INET;
  /*htonl()為將32位元主機字元順序轉成網路字元順序*/
  server_address.sin_addr.s_addr = htonl(INADDR_ANY);
  /*htons()為將16位元主機字元順序轉成網路字元順序*/
  server_address.sin_port = htons(PORT);
  server_len = sizeof(server_address);
  /*對socket定址,建立通訊端*/
  bind(server_sockfd,(struct sockaddr *)&server_address,server_len);

  /*等待連結,建立連結佇列,起始化readfds以處理來自server_sockfd的輸入*/
  listen(server_sockfd,MAXSOCKFD);
  FD_ZERO(&readfds);
  FD_SET(server_sockfd,&readfds);

i=0;
  while(1)
  {
    testfds=readfds;


printf("使用IP:%s 備用IP=%s\n",ipstr+(0*IPSLEN),ipstr+(1*IPSLEN));
printf("111 伺服器等待中:與使用者通訊(已接到使用者傳來的資料)共%d次 \n",i);
i+=1;

    /*select()為:"先等待,直到有東西進來"的方式等待輸入的抵達在這裡是指伺服端將等待
    到使用者端有傳來資料,所以"會停在這裡"一直等到有東西進來
    則如此可避免"忙碌等待"即不斷掃描是否有資料抵達的等待方式(忙碌等待很損耗CPU時間)*/
    result = select(FD_SETSIZE,&testfds,(fd_set *)0,(fd_set *)0,(struct timeval *)0);
    if(result < 1)
    {
      perror("0000000000");
      exit(1);
    }
    for(fd=0; fd < FD_SETSIZE ;fd++)
    {
      if(FD_ISSET(fd,&testfds))
      {

        if(fd == server_sockfd)
        {
/*#################################################################################*/
          client_len = sizeof(client_address);
          client_sockfd = accept(server_sockfd,(struct sockaddr *)&client_address,&client_len);
          FD_SET(client_sockfd,&readfds);

          printf("222 接收到使用者的連線要求 fd=%d\n",client_sockfd);
/*#################################################################################*/

        }
        else
        {
          ioctl(fd,FIONREAD,&nread);
          if(nread == 0)
          {
            close(fd);
            FD_CLR(fd,&readfds);
            printf("333 使用者已離線 fd=%d \n",fd);

          }
          else
          {
            read(fd,&ch,1);
            printf("444 伺服器已取得使用者傳來的字串=%c fd=%d \n",ch,fd);
            /*fd可做為區分是哪一位使用者的旗標值*/

/*建立新執行緒以執行lee_newipt(),要傳遞的參數必須先轉型成void型態*/
/*進行IP迴避*/
if(ch == '!')
{

  shutdown(client_sockfd,2);/*關閉可疑使用者的連線*/

/*  res=pthread_create(&a_thread,NULL,lee_newipt,(void *)ipstr+(1*IPSLEN));
*/
  /*取得浮動IP*/
/*  for(i=0;i<ethmax;i++)
    memset(ipstr+(i*IPSLEN),'\0',IPSLEN);
  lee_newip(ETHSTR,ethfoot,ethend,ipstr,IPSLEN);/*一次取得全部的IP*/

/*lee_runnewip("ppp",0,1);


/**/lee_getaddrl("ppp0",ipstr+(0*IPSLEN),SG_IP);
/**/lee_getaddrl("ppp1",ipstr+(1*IPSLEN),SG_IP);

break;
}
else
{
            if((fd%2) == 1)
              ch++;
            else
              ch='A';

            write(fd,&ch,1);
}

          }/*else END*/
        }/*else END*/
      }/*if(FD_ISSET(fd,&testfds)) END*/
    }/*for(fd=0; fd < FD_SETSIZE ;fd++) END*/

printf("..............................................................................\n");

  }
printf("程式結束\n");
/*pthread_exit(NULL);/*執行緒作用完畢,終止該執行緒*/

}



非常感謝 :D

44
Network 討論版 / 請問這些IP代表的意義
« 於: 2007-03-08 14:53 »
SIOCGIFADDR=應該是ppp的公共IP但在eth0:0的是代表什麼
SIOCGIFDSTADDR=這個應該就是閘道器了(為何eth0:0的與IP相同)
SIOCGIFBRDADDR=不瞭@@~*
SIOCGIFNETMASK=不瞭@@~*

這些是程式取出設備的IP
代碼: [選擇]

  Electric Fence 2.2.0 Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
eth0:0 SIOCGIFADDR=192.168.1.11
eth0:0 SIOCGIFDSTADDR=192.168.1.11
eth0:0 SIOCGIFBRDADDR=192.168.1.255
eth0:0 SIOCGIFNETMASK=255.255.255.0

ppp0 SIOCGIFADDR=122.123.135.181
ppp0 SIOCGIFDSTADDR=122.123.128.254
ppp0 SIOCGIFBRDADDR=0.0.0.0
ppp0 SIOCGIFNETMASK=255.255.255.255

ppp1 SIOCGIFADDR=122.123.136.33
ppp1 SIOCGIFDSTADDR=122.123.128.254
ppp1 SIOCGIFBRDADDR=0.0.0.0
ppp1 SIOCGIFNETMASK=255.255.255.255

lo SIOCGIFADDR=127.0.0.1
lo SIOCGIFDSTADDR=127.0.0.1
lo SIOCGIFBRDADDR=127.255.255.255
lo SIOCGIFNETMASK=255.0.0.0



這是以ifconfig指令出來的資訊:
代碼: [選擇]

[stlee@localhost sbin]$ ./ifconfig
eth0      Link encap:Ethernet  HWaddr 00:C0:26:6C:EE:18
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2900 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2926 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:244414 (238.6 Kb)  TX bytes:316227 (308.8 Kb)
          Interrupt:9 Base address:0xc000

eth0:0    Link encap:Ethernet  HWaddr 00:C0:26:6C:EE:18
          inet addr:192.168.1.11  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:7 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:222 (222.0 b)  TX bytes:30 (30.0 b)
          Interrupt:9 Base address:0xc000

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:125 errors:0 dropped:0 overruns:0 frame:0
          TX packets:125 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:8534 (8.3 Kb)  TX bytes:8534 (8.3 Kb)

ppp0      Link encap:Point-to-Point Protocol
          inet addr:122.123.135.181  P-t-P:122.123.128.254  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1492  Metric:1
          RX packets:2789 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2793 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3
          RX bytes:176076 (171.9 Kb)  TX bytes:246537 (240.7 Kb)

ppp1      Link encap:Point-to-Point Protocol
          inet addr:122.123.136.33  P-t-P:122.123.128.254  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1492  Metric:1
          RX packets:7 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3
          RX bytes:222 (222.0 b)  TX bytes:30 (30.0 b)

[stlee@localhost sbin]$


非常感謝喔 :D

45
Study-Area 公開討論版 / 一個自私的小問題
« 於: 2007-03-06 21:18 »
小弟在使用貴站做筆記後發現真的很好用,尤其是重灌(請不要笑我,這是小弟"獨門"功力提昇
法)以前都是翻書翻得要死,現在只要進入貴站看一下之前失敗及成功的地方就很快可恢復之
前的狀態繼續操作

不過這也有一個小問題,因為在筆記或討論內,有時會有一些超連結到其他討論文章的需要
所以發現,此超連結都只針對"文章主題"但其中有用到的可能是"該主題其中的一篇討論"
不知道可不可以這樣做呢 :D 謝謝

46
酷!學園 精華區 / C語言-寫作風格
« 於: 2007-03-01 16:13 »
又再重灌了,來打屁一下吧!

風格這種東西就像藝術,每個人都有不同的標準,您說這樣好,我說那樣棒,都沒個準的
不過如果是"良好習慣"的風格,相信寫程式這回事就不是什麼痛苦的事了
其實寫程式不辛苦,辛苦(痛苦)的是debug除錯了,以前曾花一天寫了一個自認為滿屌的功能
後來這個功能花了兩個禮拜去除錯--->真的是太屌了
至於"良好習慣"其實本人沒受過正規訓練,只是一些經驗談,因為覺得學電腦不是在學"成功"
的經驗而是要去學習"失敗的經驗",您沒失敗過怎麼知道這樣做不行,那樣做可以呢,而且我很
多朋友知道我會寫程式,直覺的都認為我"電腦一定很厲害"....

會寫程式可不是筋開,腰軟,會旋轉了 :lol: 不會的更多阿

來說說我的失敗經驗吧
程式最忌幫使用者預設他的使用範圍,當然這需要一點實做經驗
才能有所體會,所謂實做經驗就是被客戶要求改東改西然後原來寫的幾乎體無完膚或作廢
悶著頭寫程式的品質會不錯(內行人看起來),可是您寫的程式是要給他使用上手後您會
翹起大拇指對他說"您真內行"^^!還是那些電腦白痴呢?(我遇到的都是後者)
所以寫作期間與未來的使用者進行溝通是必要的,您不一定要跟他討論技術細節,只要在寫
作某項功能(搜尋想怎麼打,日期要不要加等等的)跟他問一下,當您開始跟他溝通後,他反而
會開始提供您當初想都想不到的一些情報(相信我,我吃過這種甜頭)雖然很多都是沒用的
可是要的是那些偶爾才出現的"天籟之音"啊,幾通電話的投資報酬率是很高的 :wink:

事前的規劃(資料蒐集)應佔很大的比重,前年寫過一個職棒三四星的計算軟體(比六和彩複
雜100倍),約年初一月寫三月底交件,事後也沒遇到很大的bug(測試兩個禮拜中抓到一些
小bug)然後客戶用到現在也沒說有問題^^,是我功力高強嗎?還是我筋開,腰軟,會旋轉了,
都不是.....在寫作開始前(大前年中秋後)就開始蒐集資料及一些紙上作業,並請教客戶她
們實際運作狀況等等到實際上機寫程式時其實只是做一些使用者操作介面及更早之前程式
(也是我寫的相關軟體)的資料上的連結(不能叫他分開算吧)而已,其實寫的時候是很快樂
的啦並沒有痛苦(抓蟲抓到人都要彌留了)的事情發生^^

寫作時成對的東西連著打,比如叫用malloc(a)後馬上跟著free(a)然後中間再隔一些空
白列,if()時裡面的判斷式別想一行搞定很複雜的判斷
if((((a==b || b==c) &&(aa())) || (c=d)) && (c==(bb()+x) && cc()))
別跟我說您看得懂上面是啥東西,我自己都不知道在寫什麼了別說看懂
可是如果是這樣
代碼: [選擇]

if(
    (
      (
        (
          (a==b || b==c) && aa()
        ) ||  
        (c==d)
      )
    ) &&
    ( c==(bb()+x) &&
      cc()
    )
  )

if()裡面也是可以縮排的啦 :wink:

快跑完了....有空再補充吧

47
1.府前路保安宮(保安路)附近有一間賣豬心冬粉+豬腳肉的,現在很多賣豬心冬粉的煮法都模仿這一家的

2.忠義路天公廟巷子出來的福樂喜餅,他們的草莓大福對女性朋友(我老婆)來說是人間極品

3.安平陳家蚵捲那條路(安平路的另一頭)有一間賣牛肉湯的,肉香不必說了,飯可以吃到死
還有肉燥自己淋--->老闆是出來做善事的???

4.火鍋一定要吃"瑞穗",路名忘了(花園夜市那條路往中正路方向走總店在右手邊, 2店在左手
邊)他們的豬牛肉爐湯頭不必說,一定要叫一盤牛肉給他涮到三分熟後沾上湯頭加少許醬油的
調味料(自已調)不然會後悔

5.薑母鴨就吃林森路與府前路交叉口(衛生所旁)那一間,麵線必點,鴨肉丸子也必點其他隨意

6.中山公園門口那間賣土魠魚羹的,目前只有吃到那間是"正"紅燒口味的(目前台灣的土魠
魚都有分季節,冬天吃到的魚肉較軟爛,夏天的魚肉較有彈性又Q)

大概就醬了..還有路名更難報本身沒有店名的下次有機會再報了

48
C/C++程式設計討論區 / C語言-指標
« 於: 2007-02-26 15:53 »
正在重灌Linux等它安裝套件滿無聊的,寫一些東西打發一下時間
這是個人主觀上的一些概念,所以如果與您認知有所不同或有錯誤的請不吝指教,謝謝

一般來說如果是學習C語言,老師都會跟您說"指標"在C語言是最重要(意思是很難)且不可
不學的一樣東西,學會它等於武俠小說寫的"打通任督二脈"了
(事實上....不會難但打通任督二脈可不是國畫大師在畫老虎跟蘭花喔)
這樣說起來"指標"就"很難"了??其實一樣東西"困難"與否本人認為是心態的問題,與這樣
東西背後的技術或其他並沒有直接的任何關係,所以您只要認定"指標"是"很簡單"的她就
會很簡單了
之前曾在yahoo(在那裡的藝名叫相殺啦)的知識+貼過一個回應,現將其內容稍微修改如
下,其中有程式碼的部份並沒有測試過,所以如果您有這方面的興趣可以將它編譯看看有問
題的話其實不會很困難修改,只要您有"觀念"相信一定能夠把它改得比我好的

指標的觀念就是:[起點]而型別就是限定指標的[終點]

char s[10][7];
char *p;

*p=s
*p=&s
p=s
p=&s
這四個使用方式的使用時機則看需要而且結果會完全不同:
例如在一函數要傳遞私有變數給另一函數

代碼: [選擇]

aaa{}
{
  char s[10][7];

  bbb(s[0][0]);
}
bbb(char *str)
{
  int i;

  for(i=0;i<5;i++)
    printf("%s\n",str+(i*7));
}

上例中str是bbb()的私有變數(私有變數就是說str的壽命僅在bbb函數內)接收了一個
字串型別的指標變數,問題是該變數怎麼知道要從哪裡取得資料開始顯示呢?
所以在aaa()中給出s[0][0]的位址,而bbb()函數的str因為宣告成指標所以它接收的是
一個位址也就是aaa()函數中s[][]在記憶體所在的起點s[0][0],因為宣告的是字串所以
s[][0]必須在最後一個元素也就是s[n][6]內放置一個字串結束字元否則就會溢位
(溢位是個大問題)

這也是前面[型別限定其終點]的觀念,因為char只有1Byte而程式並不知道要I/O多少個
Byte所以字串從後面算來最少要有一個字串結束字元才能告訴它:喂!到這裡(字串結束字
元)該停止I/O了喔

這是字串,但非char則要看所在系統,編譯器,硬體環境了,用比較簡單的說法來說16位元
作業系統它的int應該就是16位元(2Byte)long則為int的兩倍,float則與long相當,倍精
float則為long兩倍而32位元系統int為32位元(4Byte)................

注意到了嗎!只要不是char的它所佔的位元數是固定的(除非作業統不同)所以不用像
char一樣要某個特殊字元('\0'或'\n')告訴程式應I/O多少個Byte例如遇到int每次就是取
2或4個Byte做I/O可是因為非char就是數字啊,程式該如何知道傳來的是應I/O的數字還
是一個位址的起點呢,所以這就要用取址符號'&'來傳遞非char的指標了
代碼: [選擇]

aaa{}
{
  int s[10];

  bbb(&s[0]);
}
bbb(int *x)
{
  int i;

  for(i=0;i<5;i++)
    printf("%d\n",*(x+i));
}

以int傳遞時bbb()已接收到一個位址其型別是int(所以要取用2或4Byte)故*(x+i)即能
正確的取用到每一個元素裡面的值了而char因為無法知道應取用多少Byte所以需
str+(i*7)才能正確I/O到每一個元素

總之指標指向一記憶體位置為起點,其型別規範其行為
底下的連結文章是在其它討論區貼的(就是本討論區啦)也是關於指標,參考看看
http://phorum.study-area.org/viewtopic.php?p=202836&highlight=#202836

還有一般來說int型別就是作業系統的定址能力因為比如16位元作業系統定址能力是
0~65535共65536Byte則int型別就是16位元這樣就能在該作業系統下定址到所有記憶
體,所以指標都是int的,宣告成其它型別只是規範它的行為而其本質仍為int

當然指標的應用還有更多(**a(指向指標的指標,遠程指標)不算什麼,有看過***a的呢)只
是列出其觀念的部份希望對您能有所幫助.

嗯...跑到第三片了.... :D

49
請問:

當取得兩個浮動IP時以自己寫的server程式聆聽用戶端訊息發生下列狀況(應該不是程式bug
之前是每次要連都要在bash下手動關閉,開啟ppp0及ppp1甚至重新開機)

當使用端以ppp0的介面傳送資料時傳到第10次即令其傳送server認定的"非正常使用者"的
識別字,當server接到這個識別字即開始進行"IP迴避"(即以system()叫用ifdown後再叫用ifup重新取得IP)

在測試過程中以ppp0的IP(使用端需填入的連線目標)來進行資料傳送時,當server進行IP迴避後使用端
只要手動變更連線目標的IP即可再進行連線傳送資料(還沒發展到自動)
但是以ppp1的IP進行資料傳送時卻無法進行連線(第一次連線也不行,很像這個IP沒用了)

應該是和設定的問題有關(程式的server端能正確進行資料接收及IP迴避,使用端能正常傳送資料所以應該不是程式問題了)

請有瞭解的大大能解疑一下(有說不清楚的,請告知將會補充)

謝謝,感恩

忘了告知配備:
電腦2台-其中server端有2塊網卡(一塊一個IP),使用端有1塊網卡
中華電信ADSL線路1條

50
不好意思這個問題可能與本版無關,可是不知道要貼到哪裡所以在這裡問一下

前天中華電信打電話來說要幫我的網路升級
1.原來的8M要幫我升級成10M/2M
2.線路換成光纖的
3.然後月租費從一千多變成每月固定939元,而且完全不必再花其他費用(如設定費牽線費等)
4.再送我四樣東西
_MOD(有AV端子可接到電視機看電視,我老婆本來不要換一聽到這個馬上爽的跟什麼似的)
_HP事務機一台
_中油500元油卷
_簡訊什麼的(沒用到沒仔細問)

(原因是他們要推廣光纖)

聽到這麼好康當場褲子濕一半掉,馬上叫他來牽(到現在還以為有人在框我)

所以想問一下有人有遇到過這麼好康的事嗎

51
狀況如下:
想寫一個伺服器/使用者的應用程式,主要是可讓該應用程式有網路的功能
比如一個進銷存系統,可在不同地方都連上網路共享資源且可以抓取其他網站資
料的一個應用程式,因為擔心惡意入侵的問題所以希望能不要使用固定的IP或主機名稱
如果有要連上系統則打個電話到某家分店詢問IP後輸入即可連上真正的主機(先連到分店
應用程式存有主機傳來目前所使用的IP,依此IP新加入的電腦可連到主機)
所以該應用程式(還沒寫好但已能取得PPP0介面的IP)預定可透過系統取得中華電信浮動
式的二個IP後其中一個為正常連線使用,另一個IP由主機取得後向以連線上來的使用者傳
回做為預定下次(不固定分鐘數後第一個IP即斷線)連線的位置,希望能透過這樣交叉變換
IP的方式達到"完全不相干者"的惡意入侵(相干者的入侵可能無法預防)

目前問題:(希望解決)
因為不會設定所以電腦上只能取得一個PPP0介面公共IP(希望能取得兩個以上)
硬體方面目前有兩台電腦3塊網路卡可供運用
最希望的解決方案是能在壹台電腦兩塊網路卡的情形下取得兩個中華電信所提供的
浮動式公共IP(例如能有PPP0及PPP1兩個介面)

謝謝!多謝您的幫忙...感恩T.T

52
請問如何以一般使用者身份寫一個程式可取得中華電信所給的浮動式IP
以下面的代碼只能取得127.0.0.1請問該如何修改才能取得每次連線的浮動IP
代碼: [選擇]

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>

main()
{

  struct hostent *hp;
  struct in_addr in;
  struct sockaddr_in local_addr;
  char myname[256];
  char *host,**names,**addrs;

  struct sockaddr_in address;
  struct hostent *hostinfo;
  struct servent *servinfo;
  struct servent *s;
  int sockfd,len,result;

  gethostname(myname,255);
  host=myname;


  hostinfo=gethostbyname(host);
  if(!hostinfo)
  {
    printf("錯誤 myname=%s \n",myname);
    return;
  }

  printf("host=%s\n",host);
  printf("h_name=%s\n",hostinfo->h_name);

  names=hostinfo->h_aliases;
  while(*names)
  {
    printf("*names=%s\n",*names);
    names++;
  }

  addrs=hostinfo->h_addr_list;
  while(*addrs)
  {
    printf("*addrs=%s\n",inet_ntoa(*(struct in_addr *)*addrs));
    addrs++;
  }

printf("11111111111111111111111111111111111111\n");

  s=getservbyport(htons(23),"tcp");
  printf("%s %d/%s\n",s->s_name,ntohs(s->s_port),s->s_proto);

printf("22222222222222222222222222222222222222\n");

}

這是抄書上方法拼湊出來的,但試了很多種方法仍無法取得浮動的IP
目地是想寫一個沒有固定IP的伺服器(傳送新取得的IP給client端以維持連線)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
不知道這個方法可不可行???

實用方面可能需以電話或簡訊通知使用者IP(server所在)
可是不知道這樣能否達到阻絕惡意侵入(可達到阻絕惡意入侵時使用者可接受電話通知)

也就是在沒註冊[正式的主機名稱]及[固定IP]的情況下要能達到server/client的
服務,請問這有可能嗎???

53
在書上看到的client/server程式範例中有這個函數->ioctl()
翻了函數庫的書找不到有寫這個函數
所以請問一下前輩知道這個函數是做什麼的嗎???

我知道找男人man就好了.....可是...
小弟英文很爛,所以能請知道的前輩辛苦一點....用中文解釋一下
感恩!!

ps.小弟英文很爛就是只會good,thank之類的程度...T_T

54
程式討論版 / 不限位數四則運算程式原碼
« 於: 2007-01-14 13:23 »
代碼: [選擇]

rm *.o
rm go
make
gdb go

請先將這裡程式代碼的部份存成go.sh
在編譯程式時執行./go.sh即可

55
研究了一個晚上發現我的問題很豬頭
http://db.math.ust.hk/articles/history_pi/c_history_pi.htm
不過裡面有一個無窮乘積求圓周率的方法倒是可以試試
已經有取得小數點後一萬位的資料了,謝謝大家的幫忙我要開始測試了

56
想要測試一下剛寫好的程式
圓週率(就是3.14159........那一個除不盡的數字)小數點後到底牽多長了(應該有人去算它吧)
我想要算看看小數點後(100*1024*1024)位來測試程式
很像有點誇口了,不過這應該最能測出一個不限位數四則運算程式的能耐了
所以想請各位幫幫忙找一下資料
1.目前圓週率的最精準位數到哪一位數了
2.要用哪兩個數相除(不好意思以前學的還老師了)可求該數(最好長一點如10位數以上短一點也沒關係)
謝謝大家!!!

57
程式討論版 / 不限位數精準度的四則運算
« 於: 2007-01-01 20:40 »
前陣子把以前買來但是看不懂的書(買的時後以為看的懂)重翻了一遍,書名
叫做:C名題精選100則-碁峰出版,作者:先鏡光
其中的一個問題就是[不限位數精準度的正整數加法與乘法]
小弟依據裡面的概念寫了相同的[不限位數精準度的數值加法與乘法]
所謂的數值當然包含正整數與浮點數(負數部份有其它解決方案)
現在正要往減法與除法邁進,不過我想除法應該比較困難
所以想請問一下有沒有這方面的參考資料
謝謝

58
上一次可能沒把問題說清楚,這次將問題說清楚一點希望各位學長幫幫忙

我正在寫一個文書處理器,因為習慣所以我都是在主程式先寫一些相關函數,等到一段時間或一個功能段落後便將這些函數依其功用分別儲存並編入各相關的函數庫內,例如在搜尋/替換功能的字串輸入是用一個stript()函數,本文顯示是用一個名為
editdsp()函數,這些函數都是依其名稱個別儲存成同名的.c檔內
在stript()內主要是處理一個固定長度字串的輸入所以當然要有能插入及取代2種
模式的輸入,而這兩種輸入模式則分別由strfgins()及strfgrep()函數處理,當然這兩個函數並不只能處理stript()的需要,而是能接收一字串*ch將之插入或取代*s字串
內相等*ch字串長度的公用函數,所以strfgins()及strfgrep()是在另一個函數庫內
的,其間的架構如下

/home/tmp/kdic.c   這是主程式(測試各工具函數)
/home/stlee/leelib/iptdsp/  這個目錄放一些輸入與顯示的函數,如stript()
/home/stlee/leelib/string/  這個目錄放一些字串相關函數,如strfgins()

函數庫編譯是用makefile的方式,如下

#iptdsp函數庫....../home/stlee/leelib/iptdsp/makefile
LIB=libiptdsp.a
$(LIB):$(LIB)(stript.o) $(LIB)(editdsp.o).......
editdsp.o:editdsp.c
(TAB)gcc -c editdsp.c
stript.o:stript.c
(TAB)gcc -c stript.c
........
........
編譯時用go.sh內容如下
rm *.o
rm*.a
rm /home/stlee/leelib/libiptdsp.a
make
cp *.a /home/stlee/leelib


#string函數庫....../home/stlee/leelib/string/makefile
LIB=libstring.a
$(LIB):$(LIB)(strfgins.o) $(LIB)(strfgrep.o)...........
strfgins.o:strfgins.c
(TAB)gcc -c strfgins.c
strfgrep.o:strfgrep.c
(TAB)gcc -c strfgrep.c
.........
.........
編譯時用go.sh內容如下
rm *.o
rm*.a
rm /home/stlee/leelib/libstring.a
make
cp *.a /home/stlee/leelib

這兩個函數庫在編譯時都沒問題,編譯好以後會在/home/stlee/leelib/內個別產生
一個libiptdsp.a及libstring.a的函數庫

現在的問題就是:因為我是先在/home/stlee/tmp/kdic.c內將各個函數寫好再個別
依功能分編到各函數庫後發生了關聯性的問題,錯誤訊息下面在說,先看makefile

#這個makefile會編譯出執行檔go....../home/stlee/tmp/makefile
go:kdic.c
(TAB)gcc -L/home/stlee/leelib -o go kdic.c -lmenu -lstring -liptdsp -lcurses

編譯時用go.sh內容如下
rm *.o
rm go
make

發生的問題如下:在stript()有叫用strfgins()及strfgrep()這在kdic()也有叫用此兩
函數時沒有問題,但我只要在kdic()將strfgins()及strfgrep()這兩個函數刪除掉
(因為函數已測試好都沒問題所以分編到函數庫後如沒必要都將之刪除)時就有如
下的錯誤訊息:

/home/stlee/leelib/libiptdsp.a(iptstr.o)(.text+0x436):In unction 'lee_iptstr':
:undefined reference to 'lee_strfgrep'
/home/stlee/leelib/libiptdsp.a(iptstr.o)(.text+0x44d):In unction 'lee_iptstr':
:undefined reference to 'lee_strfgins'
collect2:ld returned 1 exit status
make:***[go] Error 1


當然我也有想過如果把這些函數都編到一個函數庫內應該就不會有這個問題了
可是這也將造成以後函數管理的困難(我以前就是這麼幹,結果因為可能A函數是
很久以前寫的,結果因為忘了有這個函數又寫了一個B函數;後來發現原來A函數和
B函數功能都是相同的,就這樣傻呼呼的寫了一堆以前寫過的東西)
我想這應該是make的問題,但是以我目前手上有的書關於函數庫管理的都只寫
一點點所以請學長幫幫忙看有什麼機制能達到我的需要,謝謝

59
問題發生的狀況如下:
在/home/stlee/下開發程式有一個目錄leelib裡面是存放一些已開發好的函數
因為我習慣將用途不同的函數分別存在不同的目錄內,然後將各目錄內的函數
編譯成各個不同的函數庫
/home/stlee/leelib/string目錄主要是擺一些關於字串方面的函數
/home/stlee/leelib/iptdsp目錄則是擺一些關於輸入及顯示的函數
/home/tmp目錄則是主要的開發中函數的開發區,再這裡開發好的函數會依用途將之存放在/home/stlee/leelib內,一個函數一個檔案

問題就是在/home/stlee/tmp下將函數開發完畢後將之存到例如string後以
makefile檔的方式建立函數庫/home/stlee/leelib/string.a及/home/stlee/leelib/iptdsp.a時編譯成函數庫完全沒問題但當我回到tmp要以主開發程式test.c叫用時gcc給了我一個相依性的錯誤訊息,例如strfgdel()函數是在
tring.a這一個函數庫;而在iptdsp.a函數庫內有一個iptstr()函數有叫用strfgdel()
函數,這在函數庫編譯時都很正常可是在/home/stlee/tmp/test.c內有叫用iptstr()
函數但是沒有叫用strfgdel()函數時就有這個相依性的錯誤訊息問題,只要在test.c內叫用了strfgdel()函數就不會有這一個錯誤訊息產生

請問這是怎麼回事???是不是一定要將函數庫編譯成一個xxx.a才能避免此錯誤
主程式的編譯語法如下
gcc -L/home/stlee/leelib/ -o test test.c -lcurses -lstring -liptdsp -lscrkbinit
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我覺得問題應該不是這裡但寫出來提供參考

頁: 1 [2]