UTF-8是一種可變長度Unicode編碼。使用一至四個bytes作為文字的編碼:
1. 128 個 US-ASCII 文字只需一個byte編碼。
2. 拉丁文、希臘文、亞美尼亞語、希伯來文、阿拉伯文、敘利亞文、
斯拉夫文等特殊拼音文字需要二個bytes編碼。
3. 東亞地區文字,包涵正體中文(繁體中文)、簡體中文、日文、
韓文使用三個bytes編碼。
4. 其他特殊文字則使用四個bytes編碼。
在php中常見的計算字串長度的函數有:strlen和mb_strlen,
讓我們來看在utf-8環境內會有什麼不同結果。
為了避免Blog誤判,所以這裡捨棄網頁的語法,只列出php的語法區塊。
<?php
$str='中文測試abc123';
echo 'strlen「中文測試abc123」為'.strlen($str)."<hr>";
echo 'mb_strlen「中文測試abc123」為'.mb_strlen($str,'utf8')."<hr>";
$str2='RussiaРосси́я';
echo 'strlen「RussiaРосси́я」為'.strlen($str2)."<hr>";
echo 'mb_strlen「RussiaРосси́я」為'.mb_strlen($str2,'utf8')."<hr>";
?>
輸出結果為:
strlen「中文測試abc123」為18
mb_strlen「中文測試abc123」為10
strlen「RussiaРосси́я」為20
mb_strlen「RussiaРосси́я」為13
這裡我們可以看到strlen在計算字串長度時,會依據文字類型來判斷,
中文字每一個字視為3 bytes,而斯拉夫文每一個字視為2 bytes,
所以「中文測試」這幾個字長度為3*4=12,而「Росси́я」
(斯拉夫文裡的俄羅斯)這幾個字則為2*7=14。
所以$str長度為12+6=18,而$str2長度為6+14=20
而mb_strlen在計算字串長度時,
會將一個中文字或特殊拼音文字視為長度1,
所以「中文測試」這幾個字長度為4,
而「Росси́я」(斯拉夫文裡的俄羅斯)這幾個字則為7。
所以$str長度為4+6=10,而$str2長度為6+7=13。
參考資料:
http://en.wikipedia.org/wiki/UTF-8
http://tools.ietf.org/html/rfc3629
博客來網路書店查詢
星期四, 5月 15, 2008
星期一, 5月 12, 2008
asp.net上課書籍
asp.net課程講義內容,原則上我是參考各位手上的
課本與「ASP.NET 2.0 QuickStart Tutorial」,語法部分
則參考我的vb.net課程講義組合而成。
資料庫部分,另參考旗標的「新觀念 asp.net 2.0網頁程式設計」

與碁峰的「聖殿祭司的ASP.NET 2.0專家技術手冊-使用VB」

兩本書與歷次上課的補充資料。
請點選圖示或連結就可以線上訂閱圖書..
課本與「ASP.NET 2.0 QuickStart Tutorial」,語法部分
則參考我的vb.net課程講義組合而成。
資料庫部分,另參考旗標的「新觀念 asp.net 2.0網頁程式設計」
與碁峰的「聖殿祭司的ASP.NET 2.0專家技術手冊-使用VB」
兩本書與歷次上課的補充資料。
請點選圖示或連結就可以線上訂閱圖書..
星期六, 5月 10, 2008
String(C++)
因為部落格不能使用小於符號,所以小於符號我改用全形的方式設計。
請看以下的程式:
#include <iostream>
using namespace std;
int main(){
char *s3="Welcome";
char *s5="Good morning";
s3=s5;
cout<<"s3="<<s3<<endl;
cout<<"s5="<<s5<<endl;
s5="123";
cout<<"s3="<<s3<<endl;
system("PAUSE");
return 0;
}
我們一行一行看...
char *s3="Welcome";
char *s5="Good morning";
s3與s5 沒有配置記憶體空間,"Welcome"與"Good morning"
算是編譯器在編譯期間就決定字串的位址,並沒有真正一塊記憶體
存放 "Welcome" & "Good morning"。
s3=s5;
上面這一行的意思是s3將指標指向的位址指向s5現在指向的位址
,也就是s3指標會指向 "Good morning"這一個字串位址。
s5="123";
上面這一行因為 "123"沒有記憶體空間,所以把 s5 改成 "123",
而s3 還是不變,也就是說s5指標指向 "123"這個字串的記憶體位置。
所以並沒有修改原有字串的內容。
指標要用 malloc 先配置記憶體,才可以在改變存在 malloc 產生的記憶體裡面的字串。
若是要進行字串複製動作,c與c++內不是使用=來指定,而是使用 strcpy()。
例如:
#include <iostream>
using namespace std;
int main(){
char s8[]="Good morning";
cout<<"s8="<<s8<<endl;
strcpy(s8,"this is a testing");
cout<<"s8="<<s8<<endl;
system("PAUSE");
return 0;
}
不過下面的複製字串寫法會有問題的,
因為 s3是指標但是沒有指向任何合法
可提供寫入的記憶體內。
#include <iostream>
using namespace std;
int main(){
char *s3="Good morning";
cout<<"s3="<<s3<<endl;
strcpy(s3,"this is a testing");
cout<<"s3="<<s3<<endl;
system("PAUSE");
return 0;
}
所以常用的方式就是將指標指向合法可用的記憶體區段內再來存取,
使用 malloc() 配置記憶體提供使用:
區段內都可以解決。
#include <iostream>
using namespace std;
int main(){
char *s3=(char *) malloc(sizeof(char) * 100);
strcpy(s3,"this is a testing");
cout<<"s3="<<s3<<endl;
system("PAUSE");
return 0;
}
指向其他可以寫入的記憶體:
#include <iostream>
using namespace std;
int main(){
char *s3;
char s8[]="Good morning";
s3="Welcome";
cout<<"s3="<<s3<<endl;
cout<<"s8="<<s8<<endl;
s3 = s8;
strcpy(s3,"this is a testing");
cout<<"s3="<<s3<<endl;
cout<<"s8="<<s8<<endl;
system("PAUSE");
return 0;
}
綜合以上的說明,如果是兩個指標,可以用以下的方修改字串資料:
#include <iostream>
#include <cstdlib>
using namespace std;
int main(){
char *s3,*s5;
s3=(char *)malloc(10 * sizeof(char));
strcpy(s3,"Welcome");
s5=(char *)malloc(15 * sizeof(char));
strcpy(s5,"Good morning");
cout<<"first s3="<<s3<<endl;
cout<<"first s5="<<s5<<endl;
s3=s5;
cout<<"second s3="<<s3<<endl;
cout<<"second s5="<<s5<<endl;
printf("second s3=%s\n",s3);
printf("second s5=%s\n",s5);
strcpy(s5,"123");
cout<<"third s3="<<s3<<endl;
cout<<"third s5="<<s5<<endl;
system("pause");
return 0;
}
請看以下的程式:
#include <iostream>
using namespace std;
int main(){
char *s3="Welcome";
char *s5="Good morning";
s3=s5;
cout<<"s3="<<s3<<endl;
cout<<"s5="<<s5<<endl;
s5="123";
cout<<"s3="<<s3<<endl;
system("PAUSE");
return 0;
}
我們一行一行看...
char *s3="Welcome";
char *s5="Good morning";
s3與s5 沒有配置記憶體空間,"Welcome"與"Good morning"
算是編譯器在編譯期間就決定字串的位址,並沒有真正一塊記憶體
存放 "Welcome" & "Good morning"。
s3=s5;
上面這一行的意思是s3將指標指向的位址指向s5現在指向的位址
,也就是s3指標會指向 "Good morning"這一個字串位址。
s5="123";
上面這一行因為 "123"沒有記憶體空間,所以把 s5 改成 "123",
而s3 還是不變,也就是說s5指標指向 "123"這個字串的記憶體位置。
所以並沒有修改原有字串的內容。
指標要用 malloc 先配置記憶體,才可以在改變存在 malloc 產生的記憶體裡面的字串。
若是要進行字串複製動作,c與c++內不是使用=來指定,而是使用 strcpy()。
例如:
#include <iostream>
using namespace std;
int main(){
char s8[]="Good morning";
cout<<"s8="<<s8<<endl;
strcpy(s8,"this is a testing");
cout<<"s8="<<s8<<endl;
system("PAUSE");
return 0;
}
不過下面的複製字串寫法會有問題的,
因為 s3是指標但是沒有指向任何合法
可提供寫入的記憶體內。
#include <iostream>
using namespace std;
int main(){
char *s3="Good morning";
cout<<"s3="<<s3<<endl;
strcpy(s3,"this is a testing");
cout<<"s3="<<s3<<endl;
system("PAUSE");
return 0;
}
所以常用的方式就是將指標指向合法可用的記憶體區段內再來存取,
使用 malloc() 配置記憶體提供使用:
區段內都可以解決。
#include <iostream>
using namespace std;
int main(){
char *s3=(char *) malloc(sizeof(char) * 100);
strcpy(s3,"this is a testing");
cout<<"s3="<<s3<<endl;
system("PAUSE");
return 0;
}
指向其他可以寫入的記憶體:
#include <iostream>
using namespace std;
int main(){
char *s3;
char s8[]="Good morning";
s3="Welcome";
cout<<"s3="<<s3<<endl;
cout<<"s8="<<s8<<endl;
s3 = s8;
strcpy(s3,"this is a testing");
cout<<"s3="<<s3<<endl;
cout<<"s8="<<s8<<endl;
system("PAUSE");
return 0;
}
綜合以上的說明,如果是兩個指標,可以用以下的方修改字串資料:
#include <iostream>
#include <cstdlib>
using namespace std;
int main(){
char *s3,*s5;
s3=(char *)malloc(10 * sizeof(char));
strcpy(s3,"Welcome");
s5=(char *)malloc(15 * sizeof(char));
strcpy(s5,"Good morning");
cout<<"first s3="<<s3<<endl;
cout<<"first s5="<<s5<<endl;
s3=s5;
cout<<"second s3="<<s3<<endl;
cout<<"second s5="<<s5<<endl;
printf("second s3=%s\n",s3);
printf("second s5=%s\n",s5);
strcpy(s5,"123");
cout<<"third s3="<<s3<<endl;
cout<<"third s5="<<s5<<endl;
system("pause");
return 0;
}
Win2003課程第三次到第五次的簡報檔案
這裡提供win2003課程第三次到第五次的簡報檔案,
不過這裡先提供這三次課程的原簡報檔案,
在士林分校上課所抓取的畫面,我稍後再做簡報介紹。
內容為使用者管理、時間同步、群組管理。
因下載的節點在國外,所以速度略慢,
另外,若九十天內沒有人下載,下載節點就會消失。
第三次上課原設計的簡報(上課抓取的畫面於日後再提供)
第四次上課原設計的簡報(上課抓取的畫面於日後再提供)
第五次上課原設計的簡報(上課抓取的畫面於日後再提供)
不過這裡先提供這三次課程的原簡報檔案,
在士林分校上課所抓取的畫面,我稍後再做簡報介紹。
內容為使用者管理、時間同步、群組管理。
因下載的節點在國外,所以速度略慢,
另外,若九十天內沒有人下載,下載節點就會消失。
第三次上課原設計的簡報(上課抓取的畫面於日後再提供)
第四次上課原設計的簡報(上課抓取的畫面於日後再提供)
第五次上課原設計的簡報(上課抓取的畫面於日後再提供)
String (C語言)
請看以下的程式:
#include
#include
main(){
char *s3="Welcome";
char *s5="Good morning";
s3=s5;
printf("s3=%s\n",s3);
printf("s5=%s\n",s5);
s5="123";
printf("s3=%s\n",s3);
system("PAUSE");
return 0;
}
我們一行一行看...
char *s3="Welcome";
char *s5="Good morning";
s3與s5 沒有配置記憶體空間,"Welcome"與"Good morning"
算是編譯器在編譯期間就決定字串的位址,並沒有真正一塊記憶體
存放 "Welcome" & "Good morning"。
s3=s5;
上面這一行的意思是s3將指標指向的位址指向s5現在指向的位址
,也就是s3指標會指向 "Good morning"這一個字串位址。
s5="123";
上面這一行因為 "123"沒有記憶體空間,所以把 s5 改成 "123",
而s3 還是不變,也就是說s5指標指向 "123"這個字串的記憶體位置。
所以並沒有修改原有字串的內容。
指標要用 malloc 先配置記憶體,才可以在改變存在 malloc 產生的記憶體裡面的字串。
若是要進行字串複製動作,c與c++內不是使用=來指定,而是使用 strcpy()。
例如:
#include
#include
main(){
char s8[]="Good morning";
printf("s8=%s\n",s8);
strcpy(s8,"this is a testing");
printf("s8=%s\n",s8);
system("PAUSE");
return 0;
}
不過下面的複製字串寫法會有問題的,因為 s3是指標但是沒有指向任何合法
可提供寫入的記憶體內。
#include
#include
main(){
char *s3="Good morning";
printf("s3=%s\n",s3);
strcpy(s3,"this is a testing");
printf("s3=%s\n",s3);
system("PAUSE");
return 0;
}
所以常用的方式就是將指標指向合法可用的記憶體區段內再來存取,
使用 malloc() 配置記憶體提供使用:
區段內都可以解決。
#include
#include
main(){
char *s3=(char *) malloc(sizeof(char) * 100);
strcpy(s3,"this is a testing");
printf("s3=%s\n",s3);
system("PAUSE");
return 0;
}
指向其他可以寫入的記憶體:
#include
#include
main(){
char *s3;
char s8[]="Good morning";
s3="Welcome";
printf("s3=%s\n",s3);
printf("s8=%s\n",s8);
s3 = s8;
strcpy(s3,"this is a testing");
printf("s8=%s\n",s8);
printf("s3=%s\n",s3);
system("PAUSE");
return 0;
}
綜合以上的說明,如果是兩個指標,可以用以下的方修改字串資料:
#include
#include
main(){
char *s3,*s5;
s3=malloc(10 * sizeof(char));
strcpy(s3,"Welcome");
s5=malloc(15 * sizeof(char));
strcpy(s5,"Good morning");
printf("first s3=%s\n",s3);
printf("first s5=%s\n",s5);
s3=s5;
printf("second s3=%s\n",s3);
printf("second s5=%s\n",s5);
strcpy(s5,"123");
printf("third s3=%s\n",s3);
printf("third s5=%s\n",s5);
system("pause");
return 0;
}
#include
#include
main(){
char *s3="Welcome";
char *s5="Good morning";
s3=s5;
printf("s3=%s\n",s3);
printf("s5=%s\n",s5);
s5="123";
printf("s3=%s\n",s3);
system("PAUSE");
return 0;
}
我們一行一行看...
char *s3="Welcome";
char *s5="Good morning";
s3與s5 沒有配置記憶體空間,"Welcome"與"Good morning"
算是編譯器在編譯期間就決定字串的位址,並沒有真正一塊記憶體
存放 "Welcome" & "Good morning"。
s3=s5;
上面這一行的意思是s3將指標指向的位址指向s5現在指向的位址
,也就是s3指標會指向 "Good morning"這一個字串位址。
s5="123";
上面這一行因為 "123"沒有記憶體空間,所以把 s5 改成 "123",
而s3 還是不變,也就是說s5指標指向 "123"這個字串的記憶體位置。
所以並沒有修改原有字串的內容。
指標要用 malloc 先配置記憶體,才可以在改變存在 malloc 產生的記憶體裡面的字串。
若是要進行字串複製動作,c與c++內不是使用=來指定,而是使用 strcpy()。
例如:
#include
#include
main(){
char s8[]="Good morning";
printf("s8=%s\n",s8);
strcpy(s8,"this is a testing");
printf("s8=%s\n",s8);
system("PAUSE");
return 0;
}
不過下面的複製字串寫法會有問題的,因為 s3是指標但是沒有指向任何合法
可提供寫入的記憶體內。
#include
#include
main(){
char *s3="Good morning";
printf("s3=%s\n",s3);
strcpy(s3,"this is a testing");
printf("s3=%s\n",s3);
system("PAUSE");
return 0;
}
所以常用的方式就是將指標指向合法可用的記憶體區段內再來存取,
使用 malloc() 配置記憶體提供使用:
區段內都可以解決。
#include
#include
main(){
char *s3=(char *) malloc(sizeof(char) * 100);
strcpy(s3,"this is a testing");
printf("s3=%s\n",s3);
system("PAUSE");
return 0;
}
指向其他可以寫入的記憶體:
#include
#include
main(){
char *s3;
char s8[]="Good morning";
s3="Welcome";
printf("s3=%s\n",s3);
printf("s8=%s\n",s8);
s3 = s8;
strcpy(s3,"this is a testing");
printf("s8=%s\n",s8);
printf("s3=%s\n",s3);
system("PAUSE");
return 0;
}
綜合以上的說明,如果是兩個指標,可以用以下的方修改字串資料:
#include
#include
main(){
char *s3,*s5;
s3=malloc(10 * sizeof(char));
strcpy(s3,"Welcome");
s5=malloc(15 * sizeof(char));
strcpy(s5,"Good morning");
printf("first s3=%s\n",s3);
printf("first s5=%s\n",s5);
s3=s5;
printf("second s3=%s\n",s3);
printf("second s5=%s\n",s5);
strcpy(s5,"123");
printf("third s3=%s\n",s3);
printf("third s5=%s\n",s5);
system("pause");
return 0;
}
訂閱:
文章 (Atom)