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

我的半形字符轉全形字符的代碼,發佈出來為論壇做點貢獻

答題得分者是:RedSnow
jean2004
初階會員


發表:69
回覆:80
積分:39
註冊:2004-12-18

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-10-20 06:53:15 IP:222.135.xxx.xxx 未訂閱
 
我的半形字符轉全形字符的代碼:
void __fastcall TForm1::Button1Click(TObject *Sender)
{//作者:jean(謹慎的思考),請轉載時保留
  unsigned char ch1;
  char *x;
  x=Memo1->Lines->GetText();
  int i=0;
  String hz="";
  //String hz1=Memo1->Lines->Text;
  BYTE  c,c1;
    while(x[i]!='\0')
    {
      ch1=x[i];
        if(ch1<=0x80)
        {
          c=x[i];
            if(c>' ' && c<'~')
              hz=hz String((char)163) String((char)(128 c));
            else if(c==' ')//半形空格轉換為全形
              hz=hz String((char)161) String((char)161);
            else
              hz=hz String((char)c);
          i  ;
        }
        if(ch1>0x80)
        {
          c=x[i];
          c1=x[i 1];
          hz=hz String((char)c) String((char)c1);
          i =2;
        }
    }
  Memo2->Lines->Text=hz;
}    
發表人 - jean2004 於 2005/10/20 07:22:38
jean2004
初階會員


發表:69
回覆:80
積分:39
註冊:2004-12-18

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-10-20 07:03:02 IP:222.135.xxx.xxx 未訂閱
對於這段代碼,我有兩個問題向大家請教: 1)執行效率問題,具體如下: 我用這段代碼轉換幾十KB的文本僅用3秒左右的時間,速度很快,效果很好,但是有一次我用它轉換1.8MB的文本時用了30多分鐘,但是我用一個內碼轉換軟體進行內碼轉換,僅用了4秒左右的時間,效率差別如此之大是什麼原因?這段代碼要如何改進?請各位先進一定幫忙指正 2)有沒有哪位先進寫出過全形轉半形的能否轉載一下代碼?謝謝 發表人 - jean2004 於 2005/10/20 07:24:48
justdo
高階會員


發表:2
回覆:359
積分:222
註冊:2004-08-17

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-10-20 08:15:30 IP:221.169.xxx.xxx 未訂閱
String是相當好用的,不過就是要付出一些效能的代價 簡單的來說,Sting內部會維護一個char陣列 當你一直塞資料進去,到了陣列滿了之後,他會另外跟記憶體在要一塊夠大的空間,然後把資料搬過去,再繼續接受的你塞的資料 不斷的循環這樣的過程,其實很多時候時間都白白浪費了 一個比較好的方法是自己一開始就跟系統要一個夠大的空間,自己來做塞資料的動作 String(char(c)) 之類的型態轉換也是不必要的,浪費時間而已 我只看到這些問題,其他的就有請其他高手看看囉
jean2004
初階會員


發表:69
回覆:80
積分:39
註冊:2004-12-18

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-10-21 13:37:40 IP:222.135.xxx.xxx 未訂閱
char *x=NULL;      AnsiString hz="";
  int iLong=Memo1->Lines->Text.Length();
  x=new char[iLong];
  x=Memo1->Lines->GetText();
    for(int i=0;i<=iLong;i  )
    {
        if(x[i]<=0x80)
        {
            if(x[i]>' ' && x[i]<'~')
              hz=hz String((char)163) String((char)(128 x[i]));
            else if(x[i]==' ')//半形空格轉換為全形
              hz=hz String((char)161) String((char)161);
            else
              hz=hz x[i];
        }
        else if(x[i]>0x80)
        {
          hz=hz x[i] x[i 1];
          i  ;
        }
    }
  Memo2->Lines->Text=hz;
delete [] x;    經過改進後還是很慢,何故?justdo先進,給完善一下代碼吧!
 
發表人 - jean2004 於 2005/10/21 13:43:14
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-10-21 15:26:10 IP:61.230.xxx.xxx 未訂閱
jean2004 您好:    其實 justdo 已經幫您把問題都點明了,只是您似乎仍陷在字串處理這上頭,我將您的程式修改如下,看看這樣的方式是否已經大幅度提昇了處理速度?

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    int iLong = Memo1->Lines->Text.Length();
    char *x  = new char[iLong];
    char *hz = new char[iLong*2];
    x = Memo1->Lines->GetText();
    int index=0;
    for (int i=0; i<=iLong; i  ) {
        if (x[i] <= 0x80) {
            if (x[i] > ' ' && x[i] < '~') {
                hz[index] = 163;
                hz[index 1] = 128 x[i];
                index  = 2;
            } else if (x[i] == ' ') {
                hz[index] = 161;
                hz[index 1] = 161;
                index  = 2;
            } else {
                hz[index] = x[i];
                index  ;
            }
        } else {
            hz[index] = x[i];
            hz[index 1] = x[i 1];
            index  = 2;
            i  ;
        }
    }
    Memo2->Lines->SetText(hz);
    delete [] x;
    delete [] hz;
}
7 天天敲鍵盤 v 時時按滑鼠 8
jean2004
初階會員


發表:69
回覆:80
積分:39
註冊:2004-12-18

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-10-21 17:24:43 IP:222.135.xxx.xxx 未訂閱
RedSnow版主:你好! 非常感謝版主的幫助,現在我有恍然大悟的感覺了,版主代碼的轉換速度非常的快,1.8M的資料不超過4秒,確實很快,但是我在轉換部分字元時存在相容問題,轉換後出現亂碼,我研究了半天沒有結果,最後能否請版主改進一下。 主要是轉換下面引號裏的字元時程式出錯並出現亂碼: “q yu gnv AZVV 4E02 8140 2 一 15”
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-10-21 19:37:57 IP:61.217.xxx.xxx 未訂閱
jean2004 您好:    我前一篇是針對 "執行效率" 做了修改,並未去注意其它的問題,對於您提及的問題,請試著將原先的 char 陣列改成 unsigned char,看看是否可正常運作?
unsigned char *x  = new unsigned char[iLong];
unsigned char *hz = new unsigned char[iLong*2];
7 天天敲鍵盤 v 時時按滑鼠 8
jean2004
初階會員


發表:69
回覆:80
積分:39
註冊:2004-12-18

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-10-21 20:55:48 IP:222.135.xxx.xxx 未訂閱
RedSnow版主:你好! 版主先進果然是高人! 依照版主所作的修改確實沒有任何問題了,我用那個1.8M的文本測試過,速度很快,轉換也正確,謝謝版主先進! 現在我又有兩個類似的問題,研究很久也沒有結果了,請版主一併解答一下: 問題1: Edit1->Text=ExtractFilePath("D:\\工藝文件\\YC6108工序圖1\\打中心孔.GWD"); 上面這樣運行沒有任何的問題,得到“D:\工藝文件\YC6108工序圖1\ ”,但是下面的這個卻得到了“D:\工藝檔\YC6108工序圖”是不正確的,應該得到“D:\工藝文件\YC6108工序圖1”才對: Edit1->Text=ExtractFileDir("D:\\工藝文件\\YC6108工序圖1\\打中心孔.GWD"); 原因何在? 問題2: char *x = new char[20]; char *hz = new char[20]; strcpy(x, Edit1->Text.c_str()); //x[Edit1->Text.Length()-1]='\0'; hz[0] = x[0]; hz[1] = x[1]; //hz[2] = '\0'; Edit2->Text=hz; 這段代碼運行後Edit2最後總是有一個固定的亂碼,原因何在? 找到這兩個問題的答案就可以結貼了,我也能睡的安穩了,再次謝謝版主對全形字元那個問題的幫助!謝謝!
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-10-21 22:56:49 IP:59.115.xxx.xxx 未訂閱
jean2004 您好:    經過測試後,我這邊並未發生您所描述的狀況,以下是我測試的敘述,兩者之間僅有一點差異,那就是前一個敘述傳回的字串會以反斜線符號結尾,而後一個敘述傳回字串的結尾則無反斜線符號
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    Edit1->Text=ExtractFilePath("D:\\工藝文件\\YC6108工序圖1\\打中心孔.GWD");
    Edit2->Text=ExtractFileDir("D:\\工藝文件\\YC6108工序圖1\\打中心孔.GWD");
}
第二個問題也是一樣的,我這邊也未發生亂碼現象,不過您的程式敘述有些問題,一是在您舉的例子裡來看,是沒有必要使用 new 來設定陣列大小的,而且您若是要用 new 來配置陣列大小,那也應該要有對應的 delete 敘述才對,二是您最好在使用陣列之前先將陣列內容清為零,以免有殘留資料而造成預期外的結果,您所謂的亂碼大概就是未清零所殘留的字碼,我修改後的測試碼如下,您參考一下吧:
char x[20];
char hz[20];
ZeroMemory(hz, sizeof(hz));
strcpy(x, Edit1->Text.c_str());
hz[0] = x[0];
hz[1] = x[1];
Edit2->Text = hz;
請注意,上列敘述僅針對問題做說明之用,最佳化處理不在考慮之列。 7 天天敲鍵盤 v 時時按滑鼠 8
jean2004
初階會員


發表:69
回覆:80
積分:39
註冊:2004-12-18

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-10-23 18:44:30 IP:222.135.xxx.xxx 未訂閱
感謝RedSnow版主先進的指點,第一個的問題我這裏確實出現缺少“1”字元的狀況,第二個問題我今日新建一工程測試,不管用版主先進的代碼還是用原來的確實都沒有亂嗎了,只是我原來的代碼漢字前面加空格取出來的漢字就變了,但後面沒有亂碼了,感謝版主先進!
jere
一般會員


發表:3
回覆:7
積分:2
註冊:2006-08-31

發送簡訊給我
#11 引用回覆 回覆 發表時間:2007-01-22 10:59:42 IP:59.124.xxx.xxx 訂閱
可以請請各位大大,上述的程式可以判斷由全形、半形混合的字串,變成全形嗎?
還有請問Delphi的程式碼要如何做呢?
系統時間:2024-05-08 4:47:31
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!