DELPHI提供的函数,竟然有BUG,只是郁闷之极.. ( 积分: 10 )

  • 主题发起人 主题发起人 dream0
  • 开始时间 开始时间
D

dream0

Unregistered / Unconfirmed
GUEST, unregistred user!
我说的是那个函数就是DELPHI提供的StringReplace这个函数,看看我下面的语句
procedure TForm1.Button1Click(Sender: TObject);
var
s:TStrings;
begin
s:=TStringList.Create;
s.LoadFromFile('F:/ddd/Tlist.cs');
s.Text:=StringReplace(s.Text,'OleDb','Sql',[rfReplaceAll,rfIgnoreCase]);
s.SaveToFile('F:/ddd/tlist.cs');
s.Free;
end;
'F:/ddd/Tlist.cs'这个文件的内容如下,如果要测试的朋友把他复制保存到文本文件即可
using System;
using System.Data;
using System.Data.OleDb;
/// <summary>
/// TList 的摘要说明
/// </summary>
public class TList
{
public TList()
{

}

public string GetBigList(int iListId, int iPageIndex, string sOther) //sOther用来记录版块的一些附助参数,由于在逻辑层有读出,所以传过来
{
TData tdata = new TData();
OleDbConnection conn = tdata.conn;
string sql = "SELECT * FROM wx_list WHERE fParent=" + iListId.ToString();
OleDbCommand cmd = new OleDbCommand(sql, conn);


string sBody = "";
conn.Open();
OleDbDataReader dr = cmd.ExecuteReader();

while (dr.Read())
{
sBody += "<div class='divlist'><a class='alist' href=listz" + dr["fId"].ToString()+"z1.aspx>"+ dr["fName"].ToString() + "</a></div>";
}
dr.Close();
conn.Close();

测试了的朋友一定会发现退换出来的结果,完全不是想象中的那样,,但是你把rfIgnoreCase这个参数去掉,你马上会发货又完全可以正常退换了..但是按照这个函数的正常情况的话,,加了rfIgnoreCase应该是不会有问题的,,

当然这个函数退换的时候不是所有的代码都有这个问题,,我是退换上面那段文本的时候才发现这个问题的,,我也搞不清楚上面那段文本有什么特殊的地方,从另一个角度上来说还是这个函数有BUG的...

有高见的朋友欢迎发表下..
 
我试过,一共替换了5个地方,没有发现不对的。
 
flag:=[rfReplaceAll]//注意参数
str1 := StringReplace(str, '123', '789', flag);//举个例子

没有发现不对的 ,主要看你怎么使用
 
替换结果:
using System;
using System.Data;
using System.Data.OleDb;
/// <summary>
/// TList 的摘要说明
/// </summary>
public class TList
{
public TList()
{

}

public string GetBigList(int iListId, int iPageIndex, string sOther) //sOther用来记录版块的一些附助参数,由于在逻辑层有读出,所以传过来
{
TData tdata = new TData();
OleDbConnection conn = tdata.conn;
string sql = "SELECT * FROM wx_list WHERE fParent=" + iListId.ToString();
OleDbCommand cmd = new OleDbCommand(sql, conn);


string sBody = "";
conn.Open();
OleDbDataReader dr = cmd.ExecuteReader();

while (dr.Read())
{
sBody += "<div class='divlist'><a class='alist' href=listz" + dr["fId"].ToString()+"z1.aspx>"+ dr["fName"].ToString() + "</a></div>";
}
dr.Close();
conn.Close();

没错,这个函数在 SysUtils.pas 里面

function StringReplace(const S, OldPattern, NewPattern: string;
Flags: TReplaceFlags): string;
var
SearchStr, Patt, NewStr: string;
Offset: Integer;
begin
if rfIgnoreCase in Flags then
begin
SearchStr := AnsiUpperCase(S); //rfIgnoreCase 变换大小写
Patt := AnsiUpperCase(OldPattern);
end else
begin
SearchStr := S;
Patt := OldPattern;
end;
NewStr := S;
Result := '';
while SearchStr <> '' do
begin
Offset := AnsiPos(Patt, SearchStr);
if Offset = 0 then
begin
Result := Result + NewStr;
Break;
end;
Result := Result + Copy(NewStr, 1, Offset - 1) + NewPattern;
NewStr := Copy(NewStr, Offset + Length(OldPattern), MaxInt);
if not (rfReplaceAll in Flags) then
begin
Result := Result + NewStr;
Break;
end;
SearchStr := Copy(SearchStr, Offset + Length(Patt), MaxInt);
end;
end;

这样简单的代码,难得找到 BUG
 
不可能啊,,试了好多遍的啊,我刚才又试了遍,,你们到我的代码,而且退换的也是我的那段代码试下啊,,
我退换以后会有部分代码如下

TData tdata = new TData();
SqlDbConnection conn = tdata.conn;
string sql = "SELECT * FROM wx_list WHERE fParent=" + iListId.ToString();
SqlDbCommand cmd = neSqlDbCommand(sql, conn);
 
我刚才把SysUtils.pas里面的StringReplace复制到我的单元文件中,并把其函数名改成StringReplace1还是一样没有用,然后我把这个函数的内容做了下面改改,把下面的这代码 if rfIgnoreCase in Flags then
begin
SearchStr := AnsiUpperCase(S); //rfIgnoreCase 变换大小写
Patt := AnsiUpperCase(OldPattern);

改成

if rfIgnoreCase in Flags then
begin
SearchStr := UpperCase(S); //rfIgnoreCase 变换大小写
Patt := UpperCase(OldPattern);

这段代码后,退换就变成正常了..也就是ANSI的问题,,现在我是知其然而不知其所以然了,,

高手们帮忙解决一下这是什么原因,怎么解决一下呢...
 
没有人帮忙解决一下嘛..
 
直接的S.Text中含有#0字符,无法用StringReplace替换,你需要s一行一行地替换就可以了.
 
你真的很幸运,幸亏你的 cs 源代码存成了 UTF8,假如这个 cs 源代码存成 Unicode 的话,你恐怕早晕过去啦,因为你将只看到一片空白!

令我惊奇的是:没想到,Delphi 的一个 string 的 StringReplace 函数居然可以解析 UTF8 的文本而不出错(去掉 rfIgnoreCase 参数后),佩服!
 
没有解决的方法了嘛..
 
先把文件轉換成ansistring
 
怎么转换啊..
 
后退
顶部