28 9月 2007

[Linux] 截取、忽略系統發出的segmentation fault signal

因為有個程式有需求,要暫時把segmentation fault的signal SIGSEGV這個訊號忽略掉,比較利於之後程式的debug。原本想說用single();這個function指定發生SIGSEGV時交給指定的handler function去處理,就可以忽略掉。結果…「代誌並不是憨人所想得呷呢簡單」,執行之後的結果,卻是系統不斷地發出SIGSEGV這個signal…停都停不下來,擋都擋不住...連ctrl+c都不行Orz...

原來在fault發生後,必須處理造成fault的原因,再返回程式執行,返回程式後,會重新執行faulting instruction。所以若是想忽略segmentation fault的話,就必須透過longjmp()跳過可能發生錯誤的code,然後再繼續執行。

 

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/ipc.h>
#include <setjmp.h>

jmp_buf setjmp_buffer;

void segmentFault(){
std::err<<"get a segment Fault!"<<std::endl;
longjmp( setjmp_buffer, 1 );//用0的話, setjmp()就會收到0,那麼可能會無窮回圈
}

int main(){

//當發出SIGSEGV這個signal時,交給segmentFault這個function處理
signal( SIGSEGV,(sig_t)segmentFault );

if( setjmp( setjmp_buffer ) == 0 )
{
// do something
std::cout<<"longjmp!!n";
char *a= NULL;
std::cout<<"ok"<<std::endl;
a[0] = '1';//cause a Segmentation Fault
}
else
{
// do something
std::cout<<"after longjmp.n";
}
return 0;
}

 

27 9月 2007

[Linux] php5安裝extension xslt

## 此篇文章有更新 ##
## 以下為手動compile安裝xslt+php的步驟 ##
## 至於Ubuntu+php5+xsl 請參考我的新文章 ##

由於在php4.1以後的版本對extension xslt預設不再是support,因此如果想要為php安裝xslt的話,就變得有點麻煩了。最近正好要在Fedora5上安裝Apache+PHP+XSLT+Mysql,原本一切很順利得裝起來了,但是最後才發現PHP5不support XSLT了,原本全都用yum指令安裝的,或是用rpm安裝的,全都要移除重新安裝一次…

在Linux上,由於要讓PHP5裝上XSLT,就必須要自行下載source code經過compile後才能安裝,而要compile安裝PHP的話,也必須compile安裝Apache才行。

安裝XSLT所需要的套件是Sablot,而Sablot又需要先安裝Expat,所以安裝的順序為(以下版本為參考用):

  1. Expat-2.0.1
  2. Sablot-1.03 (Sablotron)
  3. Apache (httpd-2.0.59)
  4. PHP-5.2.3

以下為我的安裝指令,--prefix的路徑是可以自己設的,以自己的主機設定為主。

  • Expat
    • ./configure
    • make
    • make install
  • Sablot
    • 要-enable-shared才能讓PHP找到XSLT的library
    • ./configure --enable-shared
    • make
    • make install
  • Apache
    • 要--enable-module才能讓PHP順利安裝
    • ./configure --prefix=/usr/local/apache2 --enable-module=so
    • make
    • make install
  • PHP
    • ./configure --prefix=/usr/local/php \
    • --with-apxs2=/usr/local/apache2/bin/apxs \
    • --with-mysql=/usr/ \
    • --enable-xslt \
    • --with-xslt-sablot
    • make
    • make install

這只是在Linux上,安裝Apache+PHP再加上PHP的extension的XSLT,如果要加上其他的extension也是差不多依樣畫胡蘆就行了。若還是不太清楚,可以下./configure --help查一查,或是看看INSTALL檔案的內容,應該就滿清楚的了。


#ps. 最近改用Ubuntu照上面的步驟安裝,卻是屢裝屢敗,硬是不給我裝起來...明明phpinfo()的結果都看得到xslt了,執行時,就是給我出現Fatal error: Call to undefined function xslt_create() 的訊息...真的很幹!
後來改用php 4.4.7安裝後,才成功。真是奇怪...

[C/C++] 用C++的Vector產生動態二維陣列

vector是c++很好用的standard library,以往自己在產生動態二維陣列時,都習慣用int ** array,然後再配合for迴圈去new出想要的array size

    //2維的array[n][n]
    int ** array_2D = new int*[n];
    for(int i=0;i<n;i++){
        array_2D[i]=new int[n];
    }


但是當量一大時,用for loop與new配置出來的效果不是很好,因此,後來用了vector,發覺此方似乎比原本上面的方法好多了

 vector<int> row;
 row.assign(n,0);//配置一個row的大小
 vector< vector<int> > array_2D;
 array_2D.assign(n,row);//配置2維

[C/C++] 千萬別把function definition & 變數definition寫入.h裡

程式碼一多,為了撰寫與維護的方便,最好的方法就是將一個.cpp檔切割成多個檔案( .cpp & .h )
但是最近撰寫了一支程式,把它切成多個file,卻莫名其妙地出現了"multiple definition of [function name] ... "這種錯誤訊息...
我仔細地觀察了又觀察,不管是正著看、反著看、倒著看…都看不出錯誤來…正當對分檔的寫法失望之餘,想回復到原本一個檔案的寫法後,才驚覺原本寫法的漏洞與缺點…
原本的一個file寫到底的code....
#include<iostream>

void a_function(){
    int a;
}

void a_problem_function(){
    int problem;
}

int main(int argc, char**argv){
    return 0;
}
把它切成多個file... 包括 .h && .cpp
a.h的內容
#ifndef A_H
#define A_H

void a_function();

void a_problem_function(){
    int problem;
}

#endif
a.cpp的內容
#include "a.h"

void a_function(){
    int a;
}
main.cpp的內容
#include<iostream>
#include "a.h"

int main(int argc, char**argv){
    return 0;
}
compile過程:
% g++ -c a.cpp                                              
% g++ a.o main.cpp                                        
...... multiple definition of `a_problem_function()'

照上面的寫法實作後 會產生這樣的問題...
奇怪!? 明明a.h不是寫了「#ifndef ... #define .... 」怎麼還會有問題呢!?
沒錯! 這樣的寫法的確是會有問題的... 並不是說寫了「#ifndef ... #define .... 」,在compile過程中,就應該只有一份a_problem_function() 而不應該出現multiple definition的問題才對呀...
其實問題是在於g++ -c a.cpp後,產生了a.o檔,這個a.o檔裡面,已經包含了一個a_problem_function()的definition,然而接下來g++ a.o main.cpp時,main.cpp又去include a.h,因此,它又想產生了一份a_problem_function(),問題就此產生了!
所以把變數definition寫入.h檔也會產生一樣的問題喲!
所以問題的徵結就在於.h檔裡面,寫入了function的definition或是變數definition,這樣子容易在多個檔案互相include時,產生multiple definition的問題,所以說囉,千萬別偷懶…直接把function definition寫在.h檔裡,是很不明智的決定!!!

[Ubuntu] 安裝phpMyAdmin

我之前已經安裝好了PHP5, Apache2, MySQL了,現在就缺phpMyAdmin來管理我的DB~

在Ubuntu上安裝上面那三個套件都很簡單
都用apt-get install就可以輕鬆安裝成功了~

原本以為用apt-get install phpmyadmin就可以了
結果Ubuntu竟然不能這樣直接安裝...Q_Q
所以只能自己做苦力囉~

首先,先至phpMyAdmindownload最新的phpMyAdmin的版本,我是下載all-languages-utf-8-only.tar.gz這個版本

% wget [URL]                                          
% tar -xvzf [file name]
% mv [director name] /var/www/
% sudo cp config.sample.inc.php config.inc.php

然後再修改config.inc.php裡面的內容~
/* Authentication type */
$cfg['Servers'][$i]['auth_type'] = 'cookie';
將cookie改成http,可以增加安全性

[Ubuntu] vim讓程式碼顯示彩色

由於Ubuntu在安裝時內建的vim是簡易版(tiny)
所以無法讓程式碼變色

因此,必需要重新安裝vim才行
 > apt-get install vim       
安裝完成後,將預設的vimrc copy至user的目錄底下
 > cp /etc/vim/vimrc  ~/.vimrc   

[2007-9-9修改]
若想增加vim的功能的話
 > vim ~/.vimrc
再將想要的功能前面的「"」 去掉即可

Ex:
要讓程式碼變色
syntax on前面的"去掉即可

 

vim還有其他很多功能
可以仔細看看vimrc中的註解,再把想要的功能的"刪掉,即可~

[Ubuntu] 用apt-get安裝tcsh

因為覺得原本的bash太乏味了,所以就想說換換口味看看,順便熟悉一下Ubuntu~
所以就選擇安裝tcsh來玩玩看

在Ubuntu中,大部分常用的軟體都可以透過apt-get install來安裝
不過由於tcsh並非原本官方support的software
所以必需利用一些小手段才能夠安裝~

方法一:
「下載source code回來make install」
失敗了....在make install時,出現了一些錯誤訊息... 所以,就試試別的方法看看囉~

方法二:
「修改sources.list,再用apt-get」
原因~因為原本apt-get update只會下載官方support的software information,因此必須再下載其他的information才行,而sources.list中就是記載要從哪下載software information的文件。

修改/etc/apt/sources.list 將後面有universe的選項去掉#

% apt-get update       
% apt-get install tcsh

就成功了 ^_^

如果要設定一些基礎的tcsh設定文件,可以到.tcshrc download.tcshrc安裝檔,就可以安裝到你的user的設定了。

如果要將user的預設的shell從bash改成tcsh
可以到/etc/passwd這個file去修改
把要改的user後面的/bin/bash改成/bin/tcsh就行了

Lifetype 1.2.x版 結合BBClone

BBClone是統計網頁瀏覽人數的好幫手
感謝之前已經有Mark大大將Lifetype與BBClone結合在一起了
詳細的文章在這邊
http://blog.markplace.net/marks_development_blog/2/2005/05/06/4

但是上面這個只適用於1.0.x版的吧
1.1.x我沒試過
筆者目前所使用的版本是1.2.1版
按照Mark大大的方法掛上去後 會產生一些問題
原因是因為Lifetype的核心有修改過
所以有部分的code會產生錯誤...

按照Mark大大的方法做完之後
index.php中原本插入在
SessionManager::init();
這一行之後的code,
只要再加上成後面有// 1.2.x 的句子
就可以了

 ///BBClone
include_once( PLOG_CLASS_PATH."class/dao/articles.class.php" );//for 1.2.x
define("_BBCLONE_DIR", PLOG_CLASS_PATH."bbclone/");
define("COUNTER", _BBCLONE_DIR."mark_page.php");
if(!isset($_COOKIE["stats_cookie_nolog"])) {
$articles =& new Articles();
if(!empty($_REQUEST['articleId'])) {
//$article = $articles->getUserArticle($_REQUEST['articleId']); //1.0.x
$article = $articles->getArticle($_REQUEST['articleId']);// 1.2.x
$pageName = $article->getTopic();
} elseif(!empty($_REQUEST['articleName'])) {
if(!empty($_REQUEST['blogId'])) {
$blogId = $_REQUEST['blogId'];
} else {
$blogs =& new Blogs();
$blogInfo = $blogs->getBlogInfoByName($_REQUEST['blogName']);
$blogId = $blogInfo->getId();
}

$article = $articles->getBlogArticleByTitle($_REQUEST['articleName'], $blogId);
$pageName = $article->getTopic();
} else {
$pageName = 'index';
}

define("_BBC_PAGE_NAME", $pageName);
if (is_readable(COUNTER)) include_once(COUNTER);
}

或是直接下載已經改好的index.php

[Linux] 在Linux底下的getch() & getche()

因為C/C++語言中的getch() & getche()都只能在windows底下執行
但是在Unix/Linux底下 就必須自己寫個function囉~

#include<termios.h>
char getch(){
    int i;//判斷是否有read到值
    char ch;
    struct termios _old, _new;

    tcgetattr (0, &_old);
    memcpy (&_new, &_old, sizeof (struct termios));
    _new.c_lflag &= ~(ICANON | ECHO);
    tcsetattr (0, TCSANOW, &_new);
    i = read (0, &ch, 1);
    tcsetattr (0, TCSANOW, &_old);
    if (i == 1)/* ch is the character to use */ 
        return ch;
    else/* there was some problem; complain, return error, whatever */ 
        printf("error!n");;
    return 0;
}

用了dp.SyntaxHighlighter後所產生的編輯問題

因為dp.SyntaxHighLighter的程式碼上色方法
是將code寫在<textarea>中
不過因為Lifetype的線上編輯器也是使用<textarea>
所以在文章新增完成後,再去編輯修改文章時就會產生問題了

因為文章裡有</textarea>這個tag
所以編輯頁面看到這個就會以為tinyMCE的編輯畫面到此為止了
結果會使得</textarea>後面的文字,全都跑去外面鬼混了…

解決方法:
templates/admin/editpost.template 75行

{$postText}
改成
{$postText|replace:'</textarea>':'&lt;/textarea>'}
這樣子的話 編輯畫面就會顯示正常了...

 

以上解法也是在網路上看到同好高手解決的
http://www.jiayun.org/plog/1_jiayun/archive/188__dpsyntaxhighlighter_ee.html

解決tinyMCE會吃掉textarea中的換行符號\n

由於lifetype1.1版以上的線上編輯器就開始使用tinyMCE
因此有個問題就存在了,tinyMCE會將<textarea></textarea>中間的換行符號n吃掉
所以在<textarea></textarea>中的文字全部都會擠成同一行

解決之道:
到lifetype的資料夾底下
lifetype / js / tinymce tiny_mce-plog.js 這個檔案裡
加入這一行
remove_linebreaks : false ,
儲存之後就ok了。

[Lex] 簡易語法教學

Lex是個古老的工具
雖然是個老東西,但是還是挺好用的!
Lex的功用主要是對一個文件寫下rule
然後產生一個compiler去paser這種文件

安裝:
  目前Lex / Flex在linux下皆可以安裝執行
  以Ubuntu為例,只要下指令
  % apt-get install flex
  即自動幫你安裝完成
  接著只要輸入指令flex即可執行Lex程式了

執行Lex的順序:
  Lex的input file,必須是*.l 的檔案 ( 副檔名為l ... 小寫的L )
  接著只要輸入指令
  % flex test.l
  然後Lex就會自動產生一個output file:lex.yy.c
  接著只要compile這個lex.yy.c 就可以執行這個token parser了
  % gcc lex.yy.c -ll
  而-ll是為了include lex的library

Lex的Input File架構:
  *.l 主要分三個部分:definition & rules & user code
  這三個部分以「%%」為分界

  definition
  %%
  rules
  %%
  user code


  definition:使用者自己定義的變數,都放在這個地方
  rulesparser對token match的規則
  user code:最後產生的lex.yy.c最底下會有一模一樣的code

Definition:
  在Definition的區間裡,可以宣告一些在rule中的code要使用的變數(寫法跟c一模一樣)
  而這些code必須用%{%} 將跨行的code包起來
  因為在這個區間的code都會被完完整整、一字不漏地output至lex.yy.c檔中
  所以在compile lex.yy.c檔時,才不會產生error!
  Ex:
  %{//要記錄parser的input file的總字數與行數
     int num_char = 0;
     int num_line = 0;
  %}
  %%
  \n { num_line++; }
  . { num_char++; }

  也可以宣告一些「rule的變數」,讓rule的寫法更簡潔
  寫法為:
  name definition
  
  Ex :
  number [0-9]+
  identifier [a-zA-Z_][a-zA-Z_0-9]*
  %%
  {number} printf("%s this token is a number\n", yytext);
  {identifier} printf("%s this token is a identifier\n", yytext);

  上面的意思其實就是...
  {[0-9]+} printf("%s this token is a number\n", yytext);
  {[a-zA-Z_][a-zA-Z_0-9]*} printf("%s this token is a identifier\n", yytext);

Rule:
  要對input file切token的規則,全寫在這裡。
  寫法的規則是:
  pattern action
  
  pattern可以輸入一些正規表示法,或是一些word,而正規表示法在此不再贅述
  想了解的人,自己想辦法吧,筆者累了....Or2...
  action則是當pattern match後,執行相對應的code(跟c一模一樣),因此這些code會原封不動地寫入output file中
  若action的code太多,則可以用"{" "}"跨行將code包起來
  Ex:
  [0-9]+ ECHO;printf("this is a number!\n");
  等同於...
  [0-9]+ {
        ECHO;
        printf("this is a number!\n");
       }
  
  在這邊有一個特別的word可以用在action中
  ECHO 可以印出yytext(match pattern的字串)中的內容至output中

Global Variable:
  這個是lex的預設變數,在寫*.l檔的definition & rule時,可以直接使用這些變數
  yyin 是lex的input來源,型態為FILE * ,初始預設為stdin
  yytext 當rule中match一個pattern時,match的string就會存在yytext中,型態為char *
  yyleng 記錄yytext的長度
  yylineno 記錄目前的yyin讀到第幾行了
  

Example:
  這是一個計算input file的總字數&行數的lex檔  

%{
int num_lines = 0, num_chars = 0;
%}

%%
\n   { ++num_lines; ++num_chars; }
.    { ++num_chars; }

%%
main()
{
yylex();
printf( "# of lines = %d, # of chars = %d\n",
num_lines, num_chars );
}

[BCB] 無法new出新的TXMLDocument

BCB中有提供一個內建的物件TXMLDocument
它可以讀進一個xml檔,並建成一個完整的tree
讓user透過它對這個xml檔做操控
而這個物件可透過拖拉Tool bar 「Internet」中的XML圖檔至編輯器中

但是如果想新建的xml的文件一多該怎麼辦?
要read進100個xml檔 就該拉100個TXMLDocument至Form中嗎?!
那這樣就太可怕了....

 

一開始我以為可以自己寫一個TXMLDocument的pointer
再去new出一個TXMLDocument的物件出來就好了....
結果卻一直有問題...
一直出現不能create TXMLDocument的error!....
TXMLDocument * obj = new TXMLDocument("");
obj->LoadFromFile("user.xml");

後來找到這篇文章才知道
http://www.tinydust.net/prog/diary/2004/02/bcbtxmldocument.html
原來不能直接使用TXMLDocument
而要透過Delphi Interface的物件去create它才行
_di_IXMLDocument

_di_IXMLDocument doc = LoadXMLDocument("user.xml");

其他操作都跟TXMLDocument都一樣了

[PHP] Linux底下 透過php呼叫外部程式執行開檔 發生錯誤

我撰寫了一個php的網頁
透過exec呼叫一個外部程式a.out
a.out裡頭執行了open file的動作
不管是用fopen() 還是ifstream.open()
原本不存在這個檔案 還是原本存在這個檔案
最後的結果都是open file fail!

讓我覺得很奇怪
明明直接由console執行這個a.out的程式
一切正常....open file success!!!


但是一透過php去執行它,開檔就會失敗....不知為何...

以下為php的code..
<?php
echo exec("/home/falldog/a.out");
?>

a.out的source code

#include <iostream>
int main(int argc, char** argv){
FILE * file = fopen("/home/falldog/aaa.txt","w");
if( file==NULL )
printf("open file error!!!n");
else
printf("open file success!!!n");
return 0;
}


試了很多次
最後才發現只要將路徑改為/tmp/就ok了
原來…透過php去呼叫a.out
可能牽涉到檔案目錄權限問題...因為/home/falldog/底下不為php網頁的權限目錄
因此,開檔時,會有錯誤發生
所以只要將這個暫存檔開啟在/tmp/就不會發生這樣的問題了

修改Lifetype的中文翻譯

如果對Lifetype中文版的中文翻譯有點不滿意的話
可以自己到 locale/locale_zh_TW.php這個檔案修改裡面的內容

因為我本人是不太喜歡將「一月」稱為「元月」,感覺很怪Tongue out
譯者不要打我...我沒有說你翻得不好....

增加SyntaxHighlighter到自己的Lifetype上

SyntaxHighlighter
是一個能為程式碼加上顏色的好物!
方法是透過javascript & css為<textarea>中的code加上顏色


主要是參考
中文翻譯者的網站:
http://www.dcaid.com/article/article.asp?tid=52

原作者網站:
http://www.dreamprojections.com/syntaxhighlighter/

首先 到這個地方下載我自行改好的程式
下載

將這個檔案解壓縮後放在lifetype的目錄下

然後到你所使用的template的目錄下
ex: templatesstandard
找到header.template與footer.template

首先在header.template裡頭的<head>...</head>之間插入

<link type="text/css" rel="stylesheet" href="SyntaxHighlighter/Styles/SyntaxHighlighter.css"></link>
<link href="SyntaxHighlighter/Styles/TestPages.css" rel="stylesheet" type="text/css">

然後再到footer.template裡頭的</body>之前插入

<script class="javascript" src="SyntaxHighlighter/Scripts/shCore.js"></script>
<script class="javascript" src="SyntaxHighlighter/Scripts/shBrushCSharp.js"></script>
<script class="javascript" src="SyntaxHighlighter/Scripts/shBrushPhp.js"></script>
<script class="javascript" src="SyntaxHighlighter/Scripts/shBrushJScript.js"></script>
<script class="javascript" src="SyntaxHighlighter/Scripts/shBrushJava.js"></script>
<script class="javascript" src="SyntaxHighlighter/Scripts/shBrushVb.js"></script>
<script class="javascript" src="SyntaxHighlighter/Scripts/shBrushSql.js"></script>
<script class="javascript" src="SyntaxHighlighter/Scripts/shBrushXml.js"></script>
<script class="javascript" src="SyntaxHighlighter/Scripts/shBrushDelphi.js"></script>
<script class="javascript" src="SyntaxHighlighter/Scripts/shBrushPython.js"></script>
<script class="javascript" src="SyntaxHighlighter/Scripts/shBrushRuby.js"></script>
<script class="javascript" src="SyntaxHighlighter/Scripts/shBrushCss.js"></script>
<script class="javascript" src="SyntaxHighlighter/Scripts/shBrushCpp.js"></script>
<script class="javascript">
dp.SyntaxHighlighter.HighlightAll('code');
</script>

[Perl] 用正規表示法做出trim的功能

trim的功能就是去掉前後多餘的空白

$var = " abc_ def_ ";
$var =~ s/^(s)+//; # 去前面空白
$var =~ s/(s)+$//; # 去後面空白
#$var結果="abc_ def_"

[Perl] 做出2維陣列

Perl有@var的1維Array
這是大家所熟悉的
至於要如何做出2維的Array呢?

在Perl裡面
如果@var是1維
那麼@@var就是2維!? 錯了!大錯特錯.... 我一開始就是這麼想的...Embarassed


其實Perl的2維陣列 是透過reference(參照)所產生出來的
ex:
my @one_dim = split(/ /, "a b c d e");
my @two_dim = (); # 此時的@two_dim還是1維的
$two_dim[0] = @one_dim; # @即是Reference, 此時的@two_dim就變2維的了!
for(my $i=0 ; $i<5 ; $i++ ){
print $two_dim[0][$i];
}

不過,這種方法有幾個缺點

缺點一:
就是,這種方法是利用「Reference」!
所以$two_dim[0]是參考了@one_dim的東西
而不是整個複製過來
因此,如果@one_dim的東西改變了
$two_dim[0]的東西(實際上也就是@one_dim的東西)也就跟著改變了!!!

缺點二:無法用foreach取得$two_dim[0]的個數
foreach( $two_dim[0] ){...}
這樣就變得很麻煩了...
如果當@two_dim有很多個element時
每一個element都需要一個1維的變數在儲存才行
而且這每一個element的名稱都要不一樣...這樣就會有砂鍋大的問題了!!!

[Perl] swap()

sub swap{
( $_[0], $_[1] ) = ( $_[1], $_[0] );
}


my $a = 100;
my $b = 200;

swap($a, $b);

print $a . ", " . $b . "n";

#結果會是200, 100

[Perl] Sub function傳入兩個以上的Array的問題...

sub FUNC{
foreach(@_){
print "$_n";
}
}
my @zzz1 = split(/ /,"ab1 cd1 ef1");
my @zzz2 = split(/ /,"ab2 cd2 ef2");

FUNC(@zzz1, @zzz2);

原本Perl的sub function傳入多個參數是允許的
但是它會自動將傳入的參數存成@_的Array
所以若傳入兩個Array當參數
則在Sub FUNC中會將這兩個Array視為一個Array...
這樣就會產生問題了...

上面的程式碼就是將@zzz1,@zzz2兩個Array傳入sub FUNC
而sub FUNC會將這兩個Array存至@_中, 視為同一個Array

[Perl] local的用法

原本local的用法
是為了怕變數被sub function更改到 才有這個用法的
因為perl原本都不用宣告就能使用參數了
所以若是
sub Test
{
$abc = 0;
}
$abc = 100;
Test();
print $abc;
#印出來的值會是0
#因為 sub function中,使用了$abc在之前就宣告了, 所以程式會拿之前宣告的$abc的memory來使用
# 所以呼叫Test()後 值就變了

因此,若是不希望sub function會改到全域(呼叫它的也可能是sub function)原有的變數
就必須在sub function裡的變數 加上local這個關鍵字
sub Test
{
local $abc = 0;
}
$abc = 100;
Test();
print $abc;
#印出來的值會是100


另外一點就是...若程式使用了
use strict
就不能使用local了
因為上面這種情形就不會出現了...凡事要用的變數都要宣告
就不會分不清楚是「區域變數」還是「全域變數」了

[PHP] -error- UTF-8檔案中存有BOM

Warning: Cannot modify header information - headers already sent by進入網頁後若出現上面的警告文字

就是當你的檔案想用UTF-8編碼時
若利用UltraEdit-32時 將ASCII轉成UTF-8時
它會自動幫你在檔案前面多加了BOM的資料
但PHP不認識,所以開啟時會出現這樣的訊息

所以若想將原本Big5編碼的檔案轉成UTF-8
可以用Notepad++選擇"格式" => "編譯成UTF-8碼(無BOM)"即可


Notepad++真是個好物啊!
大部分的程式我都用它來撰寫
Notepad++網站連結

[Perl] 精要整理

正規表示式m// 比對
s/// 取代(只取代一次)

加在字尾部分 ex: m/falldog/ig
/s 跨行比對
/g 全域取代
/i 忽略大小寫

字符集...
d 數字(digital),代表[0-9]
w 單字(word),代表[A-Za-z0-9_]
s 空白(space)
f 跳頁(form-feed)
t 跳格(tab)
n 換行(new-line)
r 回行首(carriage return)
....w* => 0個以上的單字
....w+ => 1個以上的單字

 

[Tomcat] 如何防止目錄被瀏覽?

有時候 安全性也是挺重要的
因此,若是怕目錄被別人看透的話,是可以避免的

在 tomcat安裝目錄/conf/底下,找到web.xml檔案,尋找

<init-param>
<param-name>listings</param-name>
<param-value>true</param-value>
</init-param>

把true改成false就好囉 

[JSP] 取得Client的IP

String ip = (String)request.getRemoteAddr(); 

[JSP] 將openDB、closeDB抽開來寫

通常在開發一個與資料庫連結的JSP專案時
常常每一個檔案開頭、結果都會有著同樣的code...
就是openDB, clodeDB的部分...

///一般jsp頁面要讀取資料庫寫法~
<%@ include file="../Connection/openDB.jsp" %>
...
...
<%@ include file="../Connection/closeDB.jsp" %>



///////////////////////////////////////////////////////////////////////////

///將openDB、closeDB抽出來的寫法~
//openDB.jsp的寫法
//...不能用try catch包起來...否則con這個變數只能生存在該try區塊中~
<%
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/SchoolList" );
%>


//closeDB.jsp的寫法
<%
try{
con.close();
}catch(Exception e){
out.println( e.toString() );
}
%>

[JSP] request.getParameter 中文的問題

request.getParameter 出來的結果常常會出現亂碼...這就是編碼的問題...

法1:針對單一個request
String name = new String( request.getParameter("name").getBytes("ISO-8859-1"), "Big5");


法2:針對此頁中的所有request
<%request.setCharacterEncoding("Big5");%>

[Java] 讀檔 對字串切Token

讀檔 對字串切Token

    String fileName = "xxx.txt";

FileReader fr = new FileReader( fileName );//讀檔

BufferedReader stdin = new BufferedReader( fr );
//將fr置入BufferedReader, 只有BufferedReader能readLine()



StringTokenizer stoken = null;

while( stdin.ready() ){

stoken = new StringTokenizer( stdin.readLine() );

while( stoken.hasMoreTokens() ){
System.out.println( stoken.nextToken() );
}
}
 

[Notepad++] 快速鍵改不回來

原本用Notepad++3.5版
為了修改檔案方便
DEL的快速鍵改掉成F3
結果後來就改不回來了...



後來不管是重新安裝or安裝更新版3.7版
還是沒有用

直到找到一個檔案才發現
快速鍵的設定在檔案中


1. 開啟執行對話窗(開始->執行)。注意:Notepad++ 應該關閉。
2. %APPDATA%Notepad++ 複製到執行對話窗,選取 ok,這將會開啟 Notepad++ 目錄視窗。
3. 在開啟的目錄視窗中,開啟shortcuts.xml
4. 找到

<ScintillaKeys>
....
<ScintillaKeys>

 在這個區間裡,應該就會有你所設的快速鍵的設定,把那一行刪除,儲存,就ok了

[Ubuntu] apt-get install出現錯誤

出現cdrom://Ubuntu....的錯誤訊息

必須至/etc/apt/sources.list 把那一行註解掉

[Ubuntu] 網路設定

在/etc/network/中


1. 所以我們先假設網路是由dhcp派送
我們該如何設定 eth0這張網路卡
% vim /etc/network/interfaces
auto eth0
iface eth0 inet dhcp 這樣即可


2. 若我們的IP 是固定的有該如何設
% vim /etc/network/interfaces

# The primary network interface
auto eth0
iface eth0 inet static
address 140.113.208.120
netmask 255.255.255.0
gateway 140.113.208.254
dns-nameserver 140.113.250.135


3. 另外還有loopback記得要設定(照理來說應該預設會有)
% vim /etc/network/interfaces
# The loopback network interface
auto lo
iface lo inet loopback


存檔離開 即可
別忘了 最後一步當然是重新啟動網路服務
讓新的值生效
% /etc/init.d/networking restart

DNS name servers 還有一個地方要改:
% vi /etc/resolv.conf
nameserver 140.113.250.135

從Lifetype移機至Blogger

我想這是個重要的決定,畢業自架主機不是長久的辦法,以後流量愈來愈大(可能...),所以現在用學校的網路還撐得過去,但是以後一定要想辦法移機至虛擬主機上,可能花得錢多多、限製也多多。所以倒不如移至Google的Blogger,畢竟我也是個Google的愛好者(還幻想能到Google上班呢XD)~

而原本Lifetype上使用的dp.SyntaxHighlighter也改用Google Code Pretty,這部分暫時用鴻哲提供的css吧,以後有機會再自己改一下:p