全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1921
推到 Plurk!
推到 Facebook!

拆解中文字..

尚未結案
rest
一般會員


發表:5
回覆:23
積分:5
註冊:2004-05-12

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-07-29 18:31:19 IP:202.39.xxx.xxx 未訂閱
想請各位大大為小弟解惑一下.. though已看過站內文章..不過還是無法解惑.. ........... ex. 有一個edit限制輸入20個byte 可有全形、半形混雜.. 以下是我參考站上的範例.. ...................... for i:=0 to 2 do if i=0 then //first time begin   test[i]:=copy(sl.text,1,20);    if (length(test[1])>=20) and (IsDBCSLeadByte(Byte(sl.text[20]))) then      test[i]:=copy(test[i],1,19)  else    test[i]:=copy(test[i],1,20);    Edit1.text:=test[i]; end ;    ................. 我是疑問是如果我輸入這樣的"我1e和我的我的和我的"(=20BYTE)..我的 可是如果依上述範例..這樣"的"這個字就會被載掉了 最後結果:edit1.text反而少了一個字...變成了length(18) ...請問該怎麼解決...?? thx..大大解惑..    ................................. 新手多加油,加油努力中 < >< >
領航天使
站長


發表:12216
回覆:4186
積分:4084
註冊:2001-07-25

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-07-30 05:45:24 IP:192.168.xxx.xxx 未訂閱
不知道您的目的為何 可以考慮採用 WideString 例如:
procedure Tear(s:string);
var ws:WideString; i:integer;
begin
   ws:=s;
   for i:=1 to length(ws) do
     showmessage(ws[i]);
end;
~~~Delphi K.Top討論區站長~~~
------
~~~Delphi K.Top討論區站長~~~
speedup
資深會員


發表:19
回覆:259
積分:280
註冊:2003-07-04

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-07-30 09:16:30 IP:218.168.xxx.xxx 未訂閱
因為MBCS系統中,中文字用兩個Byte,如果是中文字第一個Byte用IsDBCSLeadByte測試一定傳回true,但第二個Byte就不一定了 要解決這問題的笨方法就是從頭算過去,就可避免切到中文字的第二個Byte
 function LimitSrtLength20(s:string):string;
 var i :integer;
 begin
  if length(s) > 20 then
  begin
   i := 1;
   while i < 20 do
   if IsDBCSLeadByte(Byte(s[i])) then i := i  2
    else i := i 1;       if (i = 20) and IsDBCSLeadByte(Byte(s[i])) then 
    result := Copy(s,1,19)
   else result := Copy(s,1,20);      end else result := s; 
 end;    
混心雜欲 棄修身~唉 發表人 - speedup 於 2004/07/30 09:23:59
------
唉~
rest
一般會員


發表:5
回覆:23
積分:5
註冊:2004-05-12

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-07-30 12:21:47 IP:202.39.xxx.xxx 未訂閱
謝謝兩位大大的回答.. 不過似乎還是有問題.. 1.站長大大說用widestring..那就是把全、半形字都當作一個完整的全形字 可是我的edit(多個)每次限定一定要輸滿20個byte,除了有遇到避免切到一半全形字時才會有19個byte出現的情況.. ex."若您發表的文章中需要"(20) "$您發表的文章中需要"(19) 2.speedup大大說的..有點不懂.. (B.) if (i = 20) and IsDBCSLeadByte(Byte(s[i])) then result := Copy(s,1,19) else result := Copy(s,1,20); 上面那一段是在看i如果是全形就把i:=i 2,可是下面又設當i=20,這樣不是等於上面的就沒有作用了嗎?..還是我的理解有誤,煩請大大解惑..
領航天使
站長


發表:12216
回覆:4186
積分:4084
註冊:2001-07-25

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-07-30 12:26:52 IP:192.168.xxx.xxx 未訂閱
可否告知您真正的目的 這樣我才能就問題來解決 為何要拆解中文字? ~~~Delphi K.Top討論區站長~~~
------
~~~Delphi K.Top討論區站長~~~
rest
一般會員


發表:5
回覆:23
積分:5
註冊:2004-05-12

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-07-30 13:26:32 IP:202.39.xxx.xxx 未訂閱
站長大大您好.. 就像是一個跑馬燈.. 有好幾幕(好幾個edit)可以輸入.. 現在就是要開啟user已編的檔案(ex文字檔.).. 然後將文字拆解成固定長度..依序填入edit中.. thx...!        ................ 新手多加油,加油努力中 < >< >
領航天使
站長


發表:12216
回覆:4186
積分:4084
註冊:2001-07-25

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-07-30 13:36:47 IP:192.168.xxx.xxx 未訂閱
引言: 站長大大您好.. 就像是一個跑馬燈.. 有好幾幕(好幾個edit)可以輸入.. 現在就是要開啟user已編的檔案(ex文字檔.).. 然後將文字拆解成固定長度..依序填入edit中.. thx...!
這樣我就瞭解您的需求了 我覺得我還是會用WideString來寫 如
var ts:TStringList; S,s0:String; ws:widestring; i:integer;
begin
  ts:=TStringList.create;
  s:='我1e和我的我的和我的我1e和我的我的和我的';
  ws:=s;
  s0:='';
  for i:=1 to length(ws) do
  begin
    if length(s0 ws[i])>20 then  
    begin
      ts.add(s0);
      s0:=ws[i];
    end
    else  s0:=s0 ws[i];
  end;
  ts.add(s0);
  ts.free;
end;
~~~Delphi K.Top討論區站長~~~
------
~~~Delphi K.Top討論區站長~~~
speedup
資深會員


發表:19
回覆:259
積分:280
註冊:2003-07-04

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-07-30 13:52:21 IP:218.168.xxx.xxx 未訂閱
引言: if (i = 20) and IsDBCSLeadByte(Byte(s[i])) then result := Copy(s,1,19) else result := Copy(s,1,20); 上面那一段是在看i如果是全形就把i:=i 2,可是下面又設當i=20,這樣不是等於上面的就沒有作用了嗎?..還是我的理解有誤,煩請大大解惑..
while 迴圈跑完後i可能為20或21(因為不管中英文i一定會切到字的第一個Byte) 如果i=21那直接Copy前20回去 如果i=20那要判斷第20位置上到底是否為中文字,若是則捨去(因為要和第21個BYTE 合併才能算是完整的中文字 MBCS系統麻煩的地方就是英文字用1Byte,中文用2Byte(含全型英文),如果處理時由前往後沒啥問題碰到IsDBCSLeadByte就往後跳兩個byte 但如果隨變中間找一個Byte,如果剛好切到中文字的第二Byte就會很難判斷 混心雜欲 棄修身~唉
------
唉~
rest
一般會員


發表:5
回覆:23
積分:5
註冊:2004-05-12

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-07-30 13:55:19 IP:202.39.xxx.xxx 未訂閱
不好意思..附上一小段我自已寫的程式. sl.text(要拆解的來源檔) for i:=0 to 2 do if i=0 then //first time test[0]:=copy(sl.text,1,20); if (length(test[1])>=20) and (IsDBCSLeadByte(Byte(sl.text[20]))) then test[0]:=copy(test[0],1,19) else test[0]:=copy(test[0],1,20); Edit1.text:=test[0]; if i=1 then//second time if (length(test[0]))=19 then//我想說依test[0]的長度,給予起始的位置 test[1]:=copy(sl.text,20,20); //結束的位置也會不同 if (length(test[1])>=20) and (IsDBCSLeadByte(Byte(sl.text[39]))) then test[1]:=copy(test[1],1,19); else test[1]:=copy(test[1],1,20); edit2.text:=test[1]; else if (length(test[0])=20) then//當test[0]長度是20 test[1]:=copy(sl.text,21,20);//則從21開始當edit2的開頭 if (length(test[1])>=20) and (IsDBCSLeadByte(Byte(sl.text[40]))) then test[1]:=copy(test[1],1,19) else test[1]:=copy(test[1],1,20); edit2.text:=test[1]; ............................. 就是切secondtime的時候如果最後一個是全形,就會被切掉.. 結果edit2就變成少一個全形字了.. so煩請大大解惑(不好意思佔版面了) thx.. ....................... 新手多加油,加油努力中
rest
一般會員


發表:5
回覆:23
積分:5
註冊:2004-05-12

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-07-30 15:04:13 IP:202.39.xxx.xxx 未訂閱
謝謝站長大大和speedup大大熱心地解惑.. ... 真不好意思..我實在太肉腳了.. 站長大大的結果是會像這樣..成功了^^ 我 我1 我1e 我1e和 ... 我1e和我的我的(直到指定的長度)..<-每一次要印的長度 那請問要怎麼樣才能夠印出每一次edit要的那一行就可以了.. 不好意思..煩請再指點一下.. thx... ............................ 新手多加油,加油努力中
rest
一般會員


發表:5
回覆:23
積分:5
註冊:2004-05-12

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-07-30 15:19:50 IP:202.39.xxx.xxx 未訂閱
不好意思...我是個魯肉腳.. 就是 if length(s0)=20 then    memo3.lines.add(s0); 這樣就可以了.. ................................. 謝謝各位大大解惑..感激不盡... ................................. 新手多加油,加油努力中 < >< >
領航天使
站長


發表:12216
回覆:4186
積分:4084
註冊:2001-07-25

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-07-30 18:52:48 IP:192.168.xxx.xxx 未訂閱
引言: 不好意思...我是個魯肉腳.. 就是 if length(s0)=20 then memo3.lines.add(s0); 這樣就可以了.. ................................. 謝謝各位大大解惑..感激不盡... ................................. 新手多加油,加油努力中 < >< > < face="Verdana, Arial, Helvetica"> 很好 您自己也有努力喔 if length(s0)=20 then 這樣還是會有問題 有時候一個Edit可能只能裝19個Byte因為下一個是中文 只得輸出到下一個Edit 我想您應該如此寫比較好
var ts:TStringList; S,s0:String; ws:widestring; i:integer;
begin
  ts:=TStringList.create;
  s:='我1e和我的我的和我的我1e和我的我的和我的';
  ws:=s;
  s0:='';
  for i:=1 to length(ws) do
  begin
    if length(s0 ws[i])>20 then  
    begin
      ts.add(s0);
      s0:=ws[i];
    end
    else  s0:=s0 ws[i];
  end;
  ts.add(s0);

  edit1.text:=ts[0];
  edit2.text:=ts[1];
  edit3.text:=ts[2];      ts.free;
end;
~~~Delphi K.Top討論區站長~~~
------
~~~Delphi K.Top討論區站長~~~
rest
一般會員


發表:5
回覆:23
積分:5
註冊:2004-05-12

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-07-31 08:35:51 IP:61.229.xxx.xxx 未訂閱
哈..真地太謝謝站長大大熱心地幫我解惑..(speedup大大也是..) ......... 我本來還想說把19和20的都先存在陣列裡, 然後如果20有出現過(和19一樣的,只有最後一個字不一樣) 再把19的那個delete... 和站長大大的比起來..實在是太..< >.. .......................................... 哈..真的太謝謝各位前輩了.. ............................................. 新手多努力,努力加油中 < >< >< >
系統時間:2024-07-06 12:29:05
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!