Richedit
但我无法移除Null chars
。我可以加载我的文字,因为我使用{{1 }}
现在在这段代码中:
Stream
我已将var
strm : TMemorystream;
str : UTF8string;
ss : TStringstream;
begin
strm := tmemorystream.Create;
try
strm.LoadFromFile('C:\Text.txt');
setstring(str,PAnsichar(strm.Memory),strm.Size);
str := StringReplace(str, #0, '', [rfReplaceAll]); //This line doesn't work at all
ss := tstringstream.Create(str);
Richedit1.Lines.LoadFromStream(ss);
finally
strm.Free;
ss.Free;
end;
end;
转换为TMemorystream
以string
删除Null Chars
,然后再将其转换为StringReplace()
以使用TStringstream
加载Richedit.lines.LoadFromStream
。
但我的问题是我无法使用Null Character
删除StringReplace()
。我可以替换其他字符,但不能替换#0
。
有没有办法直接在TMemorystream
中删除空字符并将其加载到Richedit
?怎么样?如果它不可能或者非常复杂,我将文本转换为string
时如何删除它们?
感谢。
答案 0 :(得分:8)
据我所知,所有搜索/替换实用程序一次或多次将输入转换为PChar,其中'#0'是终止字符。因此,他们永远不会超过第一个Null之前的字符串部分。您可能需要设计自己的机制。只是一个简单的例子:
var
i: Integer;
begin
Assert(str <> '');
i := 1;
while i <= Length(str) do
if str[i] = #0 then
Delete(str, i, 1)
else
Inc(i);
在流中替换将同样涉及测试每个字符,然后相应地调整流,然后在决定删除之后再继续。
答案 1 :(得分:8)
Sertac的答案是准确的,你应该接受它。如果性能很重要,并且您有一个包含空字符的频繁实例的大字符串,那么您应该尝试减少堆分配的数量。以下是我将如何实现这一点:
function RemoveNull(const Input: string): string;
var
OutputLen, Index: Integer;
C: Char;
begin
SetLength(Result, Length(Input));
OutputLen := 0;
for Index := 1 to Length(Input) do
begin
C := Input[Index];
if C <> #0 then
begin
inc(OutputLen);
Result[OutputLen] := C;
end;
end;
SetLength(Result, OutputLen);
end;
如果你想直接在内存流中进行,那么你可以这样做:
procedure RemoveNullFromMemoryStream(Stream: TMemoryStream);
var
i: Integer;
pIn, pOut: PByte;
begin
pIn := Stream.Memory;
pOut := pIn;
for i := 0 to Stream.Size-1 do
begin
if pIn^ <> 0 then
begin
pOut^ := pIn^;
inc(pOut);
end;
inc(pIn);
end;
Stream.SetSize(NativeUInt(pOut)-NativeUInt(Stream.Memory));
end;