2006/09/07

颱瘋天

颱瘋天,被叫來加班
原因是塌非斯系統的產品發不出去 (塌非斯系統 Product 程式會當掉)。查了半天,終於找到了原因,以下說明之:
塌非斯系統有關產品的部分,我們有設計各相關產品的Template
在Template裏有各式 Tag,例:中心位置在北緯[lat00]度
上述由中括號 '[' ']' 包圍的就是資訊 Tag
程式找到資訊 Tag,然後會代換成正確的資料
例:中心位置在北緯[lat00]度 --> 中心位置在北緯21.5度

然而,當天發生了如下的情形:
1: while (String.Pos("[") > 0)
2: {
3:  tagstart = String.Pos("[");
4:  tagend = String.Pos("]");
5:  String = String.Delete
    (tagstart,tagend-tagstart+1); //將Tag的字串刪除
6:  String = String.Insert
    (value,tagstart); //將刪除的字串處插入實際值
7: }

上述是一個 while loop 的程式,在找出 '[' & ']',並將中間的Tag代換。
下面說明一下,出問題的 Template 與實際資料

Template裏的某一行:
[its] [tyname_ch] [tyname]

上面那一行代換成這次這個颱瘋的實際資料時,應該會是:
三十午度颱瘋 阿珠 ANNCHU

然而,程式在跑的時候,卻是以下的情形
進入loop前:
 String="[its] [tyname_ch] [tyname]"
第一次的Loop跑完:
 tagstart=1
 tagend=5
 String="三十五度颱瘋 [tyname_ch] [tyname]"
第二次
 tagstart=10
 tagend=19
 String="三十五度颱瘋 阿珠 [tyname]"
第三次
 tagstart=15
 tagend=12
 String="三十五度颱瘋 阿珠 [tyname]"

第三次跑完時,String 的值沒改變
而且 tagstart > tagend !!!??

接下來,程式就進入無窮迴圈了
(我們的 code review,目的之一就是要避免可能的無窮迴圈)

接下來的問題是,為什麼會進入無窮迴圈!?
原來,"珠"這個字的前半碼,這個BYTE的編碼與 '[' 相同
所以程式第四行處理 "三十五度颱瘋 阿珠 [tyname]" 時
 tagend = String.Pos("]") = 12

........................

後來,加班,連夜趕工
把Template裏的Tag通通改成 '[{' '}]'
這樣子的雙位元處理,就不會有這種問題了...

這個事件給我們三個重要經驗

1.中文字的處理
中文字的編碼問題本來就是相當複雜的問題
像之前有同事的做法,將 BCB 的 AnsiString 轉成 WideString
(雙位元字串) 然後再來處理...事實上,也許我們可以考慮
統一使用 UTF-8 來處理字串問題 (包括資料庫的儲存)
大家思考看看吧!!

2.Code Review
這個就是另外提議的項目,可以把文字處理,當做 Code review
的一個項目。

3.客戶服務
這次的這個問題,真的是一開始設計時未思考到的問題。雖然
大多數的時候,客戶有提出的問題,可能都不是問題;或是說
大多數的時候,客戶其實也說不清楚問題是什麼。所以,這時候
乖乖來加班吧...

沒有留言:

張貼留言