公告

國明的網路筆記

2011年11月26日 星期六

國科會計畫今年投件截止日是101年的1月2日,連投兩年都沒被接受,再試試今年,不知機會有多大?
每年都投科教處,今年改投人文處試試,希望審稿委員能高抬貴手,下筆留點新人一點機會!

2011年11月22日 星期二

發現二篇有趣的文章

《季姬擊雞記》

季姬寂,集雞,雞即棘雞。
棘雞饑嘰,季姬及箕稷濟雞。
雞既濟,躋姬笈,季姬忌,急咭雞,
雞急,繼圾幾,季姬急,即籍箕擊雞,
箕疾擊幾伎,伎即齏,雞嘰集幾基,
季姬急極屐擊雞,雞既殛,
季姬激,即記《季姬擊雞記》。


《解說》
季姬感到寂寞,羅集了一些雞來養,是那種出自荊棘叢中的野雞。
野雞餓了叫嘰嘰,季姬就拿竹箕中的小米餵牠們。
雞吃飽了,跳到季姬的書箱上,季姬怕髒,忙叱趕雞,
雞嚇急了,就接著跳到幾桌上,季姬更著急了,就借竹箕為趕雞的工具,投擊野雞,
竹箕的投速很快,卻打中了幾桌上的陶伎俑,那陶伎俑掉到地下,竟粉碎了。
季姬爭眼一瞧,雞躲在幾桌下亂叫,
季姬一怒之下,脫下木屐鞋來打雞,把雞打死了。
想著養雞的經過,季姬激動起來,就寫了這篇《 季姬擊雞記》。

---------------------------------------------------------------------------------------
《施氏食獅史》

石室詩士施氏,嗜獅,誓食十獅。
施氏時時適市視獅。
十時,適十獅適市。
是時,適施氏適市。
氏視是十獅,恃矢勢,使是十獅逝世。
氏拾是十獅屍,適石室。
石室濕,氏使侍拭石室。
石室拭,氏始試食是十獅。
食時,始識是十獅,實十石獅屍。
試釋是事。


《解說》
有一位姓施的詩人,他的名號叫石室詩士。他特別嗜好獅子,發誓要吃十頭獅子。
姓施的常常到市集裡看獅子。
十點鐘,剛好十頭獅子來到市集。
這時,剛好姓施的(也)來到市集。
姓(施)的看這十頭獅子,仗著箭的力量,使這十頭獅子死了。
姓(施)的收拾這十頭獅子,到石頭做的屋子。
石頭做的屋子很潮濕,姓(施)的命令侍者擦拭石頭做的屋子。
石頭做的屋子擦(好了),姓(施)的開始嘗試吃這十頭獅子。
吃的時候,才知道這十頭獅子,實際上是十座石頭做的獅子的屍體。
(請)試著解釋這件事。


今天博士資格考筆試終於考完了,兩個星期的忐忑,也告一段落。成績如何?暫不考量,要開始準備論文計畫發表口試。

2011年11月18日 星期五

一些BCBAnsistring使用方法 (轉貼自http://scarf0910.wordpress.com/2010/10/18/一些BCB的Ansistring使用方法/

)

c++ builder Ansistring 使用方法


Ansistring char

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “哈哈”;

char *chr = Test.c_str();

}

charAnsistring

程式碼:

#include

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString str = “Sample”;

char chr[MAX_PATH];

strcpy( chr , str.c_str() );

}

BoolAnsiString

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test=BoolToStr(CheckBox1->Checked);

}

Ansistringbool

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{ AnsiString Test=“-1

CheckBox1->Checked= StrToBool( Test );

}

intansistring

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

int i = 123;

AnsiString str = IntToStr( i );

}

AnsiStringdouble

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “123;

long double d = StrToFloat( Test );

}

doubleAnsiString

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

double d = 123.456;

AnsiString str = FloatToStr( d );

}

doubleAnsiString並四捨五入

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

long double d = 123.456121212;

AnsiString str = FloatToStrF( d , ffFixed ,5 , 4 );

//說明FloatTostrF5程式表從第幾個數字的後一位元開始四捨五入,4程式表取4位小數。

//執行後得到str123.4600:roll:

}

doubleAnsiString使用類似vbformat函數

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

double d = 123.456;

AnsiString str = FormatFloat( “000000.00 , d );

}

//得到 000123.45,當然你可以使用”# . , ; E+ E- xx”等符號,你自己試試

AnsiStringTclor

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “0x00FF8080;

TColor Col = StringToColor( Test );

}

TclorAnsiString

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

TColor Col = 0x00FF8080;

AnsiString str = ColorToString( Col );

}

消除AnsiString 中的一部分字串程式碼:

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “ABCDEF”;

int First = 3; // 消除制定開頭

int Length = 2; // 消除制定長度

AnsiString Dstr = Test.Delete( First , Length );

}//得到ABEF

AnsiString 中插入字串

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “ABCDEF”;

AnsiString Ins = “12345; // 插入串

int Pos = 3; // 在哪插

AnsiString Istr = Test.Insert( Ins , Pos );

// 得到AB12345CDEF

}

取得ansi某一位元字元

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “ABCDEF”;

AnsiString Npos = Test[3];//得到C

}

取得AnsiString裏最後一個字元

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “ABCDEF”;

char *Lstr = Test.AnsiLastChar();//得到F

}

取出AnsiString字元,這個類似vbmid函數!

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “ABCDEF”;

int First = 3; // 3開始取

  

int Length = 2; // 2

AnsiString Getstr = Test.SubString( First , Length );

// 得到CD

}

AnsiString的字母比較

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “ABCDEF”;

AnsiString Sample = “abcdef”;

int Result = Test.AnsiCompare( Sample );

// 返回1,不同!分大小寫。

}

不分大小寫字串比較

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “ABCDEF”;

AnsiString Sample = “abcdef”;

int Result = Test.AnsiCompareIC( Sample );

// 返回0,相同!沒有分大小寫,哈哈

}

AnsiString中尋找字元

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “ABCDEF”;

AnsiString Sample = “E”;

int Result = Test.Pos( Sample );

// 返回5,如果你寫Sample”haha”,就返回0,找不到,哈哈

}

AnsiString中找字串,和上一個類似

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “ABCDEF”;

AnsiString Sample = “EF”;

int Result = Test.Pos( Sample );

//返回5,即E字元的位置

}

判斷字串長度,類似vblen

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “拿金幣來”;

int Len = Test.Length();

//返回8

}

取得字串,類似vbleft

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “小蘋果然看了這篇文章”;

AnsiString SLstr = Test.SetLength(6);

}//得到“小蘋果”

檢測雙位元組字串

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString ChkStr = “你好”;

int ChkPos = 1 ;

if ( ByteType( ChkStr , ChkPos ) == mbSingleByte ){

Edit1->Text=“0;

}

else{

Edit1->Text=“1;

}//返回1,如果你寫ChkStr”fxxk”,就返回0

}

檢測空字串

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = ““;

bool chk = Test.IsEmpty();

if (chk )

Edit1->Text=“1;//返回1

}

全部變小寫

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “ABCdef”;

AnsiString Lstr = Test.LowerCase();

}

全部變大寫

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “ABCdef”;

AnsiString Ustr = Test.UpperCase();

}

類似vbTrim 的去空格函數

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “ ABCDEF “;

AnsiString TLstr = Test.TrimLeft();

AnsiString TRstr = Test.TrimRight();

AnsiString Tstr = Test.Trim();

}

但是,這個處理不了全形的空格 程式碼:

AnsiString __fastcall TForm1::TrimStr( AnsiString Tm , AnsiString LR )

{

// LR L:左除去 R:右除去 B:dou除去

int len;

// 左除去

if ( LR == “L” || LR == “B” ){

len = Tm.Length();

while ( Tm.SubString(1,1) == “ “ || Tm.SubString(1,2) == “ ”){

// 半形除去

if ( Tm.SubString(1,1) == “ “ ){

Tm = Tm.SubString(2,len);

len = Tm.Length();

}

// 全形除去

else if ( Tm.SubString(1,2) == “ ” ){

Tm = Tm.SubString(3,len);

len = Tm.Length();

}

}

}

// 右除去

if ( LR == “R” || LR == “B” ){

len = Tm.Length();

while ( Tm.SubString(len,1) == “ “ || Tm.SubString(len-1,2) == “ ” ){

// 半形除去

if ( Tm.SubString(len,1) == “ “ ){

len = Tm.Length();

Tm = Tm.SubString(1,len-1);

len = Tm.Length();

}

// 全形除去

else if ( Tm.SubString(len-1,2) == “ ” ){

len = Tm.Length();

Tm = Tm.SubString(1,len-2);

len = Tm.Length();

}

}

}

return Tm;

}

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Test = “  拳腳  ”;

AnsiString Ret = TrimStr(Test,”B”)

}

相同字元重複輸入

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Soc = AnsiString::StringOfChar( ‘*’ , 100 );

Edit1->Text=Soc ;//顯示100*

}

字串替換

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Str = “Borland C++ Builder is free”;

AnsiString From = “C++ Builder”;

AnsiString To = “Delphi”;

AnsiString Result;

Result = StringReplace( Str, From, To, TReplaceFlags() <<

rfReplaceAll << rfIgnoreCase );

//<<後是參數,得到Borland Delphi is free

}

全形變半形

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Zen = “1234567890”;

int Len = Zen.Length();

char buf[MAX_PATH];

ZeroMemory( buf, sizeof( buf ) );

LCMapString( GetUserDefaultLCID(), LCMAP_HALFWIDTH, Zen.c_str(), Len, buf, sizeof( buf ) );

AnsiString Han = AnsiString( buf );

Edit1->Text=Han;

}

半形變全形

程式碼:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

AnsiString Han = “1234567890;

int Len = Han.Length();

char buf[MAX_PATH];

ZeroMemory( buf, sizeof( buf ) );

LCMapString( GetUserDefaultLCID(), LCMAP_FULLWIDTH, Han.c_str(), Len, buf, sizeof( buf ) );

AnsiString Zen = AnsiString( buf );

}

AnsiString重載了“[]”運算符,可以將內容當做字元陣列一樣操作,不過和char[]不同的是AnsiString[]運算符的下標是從1 開始的,和DelphiString 相容。對於長度不大的AnsiString可以直接使用[]來操作,長度大的時候最好轉換成char*在使用,因為重載是通過成員函數實現的,增加了系統的調用開銷。

如:

程式碼:

AnsiString Temp = “這是一個測試的AnsiString”;

int Length = Temp.Length();

for(int i = 1; i <= Length;i++)

{

if(Temp[i] > 128)

{

//……..

//篩選其中的漢字;

i++;

}

else

{

//……非漢字的字元。

}

}

對於長度小的AnsiString不必要使用c_str()轉換成C的字串來操作。

AnsiString的構造函數有一下幾種:

程式碼:

__fastcall AnsiString();

__fastcall AnsiString(const char* src);

__fastcall AnsiString(const AnsiString& src);

__fastcall AnsiString(const char* src, unsigned char len);

__fastcall AnsiString(const wchar_t* src);

__fastcall AnsiString(int src);

__fastcall AnsiString(double src);

__fastcall AnsiString(char src);

__fastcall AnsiString(short);

__fastcall AnsiString(unsigned short);

__fastcall AnsiString(unsigned int);

__fastcall AnsiString(long);

__fastcall AnsiString(unsigned long);

__fastcall AnsiString(__int64);

__fastcall AnsiString(unsigned __int64);

__fastcall AnsiString(const WideString &src);

第一個是缺省構造函數,就是生命一個AnsiString的時候使用的,比如

程式碼:

AnsiString Str1;

第二個是將字串常量或者字元陣列或者字元指標轉換成AnsiString的構造函數,他是根據C字串的規則進行構造,即以第一個遇到的’字元作為結束字元的。常見的應用是

程式碼:

AnsiString Str2 = “TestString”;

第三個是標準的拷貝構造函數,當執行一個賦值操作的時候實際上就是使用了這個構造函數。

第四個是指定了長度和源的構造函數,他和第二個不同的是,不是以’字元作為結束字元的,而是按照指定的長度為准,這個構造函數可以突破C語言中字元 串的限制和不足,可能在實際中更具使用價值,大多數的API返回的都是char*,但並不一定都是可視的字元,也可能包含了’,就可以使用這個構造函數來實現對內容的拷貝,儘管第二個參數是unisgned char類型,但是實際中使用好像可以突破256的限制,在一定意義上將這個構造函數可以是我們在使用BCB的時候避免使用new來分配char類型的數 組資料,在一個局部的應用中,使用AnsiString保存臨時的char陣列資料,不需要考慮在什麼異常的情況下需要釋放記憶體,因為超出作用域的時候,AnsiString是可以自己釋放的。

第五個構造函數可以是的AnsiString可以直接和wchar_t*進行轉換,就是可以直接將w_chart*使用=賦值給AnsiString類型。

第六個是將整型轉換為字串的構造函數,也就是可以直接將一個int類型的值賦給AnsiString,其結果和通過IntToStr賦值一樣的。

如:

程式碼:

int Temp = 46573284;

AnsiString Str3 IntToStr(Temp);

AnsiString Str4 Temp;

結果是一樣的。

第七個至第十五個和第六個類似,作用也相當。

第十六個是將WindowsWideString轉換為AnsiString的構造函數,也就是可以直接將WideString賦值給AnsiString,而不需要使用其他的方法或者API進行轉換,功能和AnsiString(wchar_t*)類似。

Stringstring是不同的,string是標準從c++支援的處理字串的類,在c++裏我們經常這樣使用string

程式碼:

cout<

但我們不能直接把String像這樣使用,但String其實重載了<<這個操作符,如果要這樣使用我們必須在頭部加入:

#define VCL_IOSTREAM

這樣我們可以這樣了:

程式碼:

String str=“hello world”;

cout<

同理,我們還可以這樣:

程式碼:

String str;

cin>>str;

在使用stl的時候,我們經常需要string,但String沒有提供直接轉換為string的方法,但我們可以這樣:

程式碼:

//—————————————————————————

#pragma hdrstop

#include

#include

#define VCL_IOSTREAM

#include

//—————————————————————————

using namespace std;

#pragma argsused

int main(int argc, char* argv[])

{

String str=“hello world”;

string ss(str.c_str());

cout< system(“pause”);

return 0;

}

這時我們可以使用stl的強大能力來處理String了。

混用AnsiStringc_str()的安全問題by nethobo

  當你使用返回AnsiString類型變數的函數,當你要寫一個返回AnsiString變數(不是指標也不是引用)函數時,或者當你使用一個以AnsiString變數為參數的函數,或者當你整天用VCL控制項傳入傳出AnsiString屬性變數時,當這個AnsiString變數

包含很長一個字串時,你是否有些擔心有些不安?擔心物件的構造與析構,更擔心的是大字串的複製(分配記憶體、記憶體複製、刪除記憶體)所帶來的效率問題?如果你是一個完美主義者或者是一個比較負責的程式作者比較關係程式效率的話,我想你一定在每次使用時都有與我一樣的這種不安的感覺。

  另外當你想要對一個AnsiString變數所含的字串進行cchar*裸字串操作時,你用AnsiString::c_str()獲得char*的指針然後對其進行c字串操作,這時你是否

會擔心你所作的是否會與AnsiString衝突呢,當然前提是你不想一上來就用strcpy

自己作一拷貝(還是效率問題)。

  下面我就本人近來幾天編程中發現的問題來探討一下AnsiString的效率問題及其c_str()的安全問題。

  BCB的提供了操作動態字串的類AnsiStringunicode版的WideString

而且在VCL類中凡用到字串類型時都是使用的AnsiString。但有時用

cchar*裸字串來處理一些問題更方便,尤其是在一些編碼與解碼演算法中。

為此AnsiString提供了c_str()函數以返回其內部的char*指針供使用(WideString

中為c_bstr(),問題類似,以下只以AnsiStringc_str為例)。

  首先我們看看第二個問題(它和第一個問題直接相關),看下面的程式碼:

AnsiString src=“test AnsiString”;

AnsiString strTest=src; //拷貝構造

char* cp=strTest.c_str();

cp[0]=’T';

運行完後,strTestsrc的值是什麼呢?結果可能與你所預想的大不相同,兩都的值都變成了”Test AnsiString”!也就是說cp[0]=T'的操作同時改變了兩個AnsiString變數的值。為什麼會這樣呢,執行時按下Ctrl滑鼠單擊兩個變數名,你會發現它們兩個所指向內部字串是同一個!也就是說在拷貝構造(賦值也一樣)時並沒有象我們想像的那樣進行內部字串的複製!好了到現在為至我們至少不用為第一個問題擔心了,沒有了字串的複製,單單是物件的構造與析構算不了什麼問題了(AnsiString只有一個Data成員變數)。

  然而第二個問題就很嚴重了,再看下面的程式碼:

AnsiString src=“test AnsiString”;

AnsiString strTest=src; //拷貝構造

strTest[1]=’x';

char* cp=strTest.c_str();

cp[0]=’T';

運行結果就是我們的預期了,為什麼加了句strTest[1]=x';正常了呢?很明顯AnsiString為了我們第一個問題中的效率問題採用了copy on write技術,也就是唯讀共用,寫時拷貝。這樣只有在物件要改變其內部資料的值時才做一份自己的拷貝然後在自己的拷貝中進行修改(就種技術在作業系統中被廣泛使用)。同時在物件析構時如果引用計數大於0,資料也不會被刪除,它保證資料的有效性。這樣返回AnsiString變數的函數也就沒有嚴重的效率問題了。

  到目前為止,已經真象大白了,結論就是我們不用擔心VCLAnsiString變數傳值的效率問題,另外即使是傳值得到的AnsiString物件,我們也不能對其內部資料直接進行修改(否則你的程式的某些功能模組可以會出現第一次運行正常第二次後就亂七八糟),尤其是在多線程環境下。原因就不必多說了,大不了複製一份了事。