从 pascal 中的字符串中删除 char 会导致控制台 pascal 中出现问号

Removing char from string in pascal cause question marks in console pascal

我正在尝试编写一个简单的程序来删除字符串中的所有 'o' 个字母。 示例:

I love cats 

输出:

I lve cats

我写了下面的代码:

var 
    x:integer;
    text:string;
    text_no_o:string;
begin
text:='I love cats';
   for x := 0  to  Length(text) do
   //writeln(Ord(text[6]));
   if(Ord(text[x])=111) then    
   else
    text_no_o[x]:=text[x];
    write(text_no_o);
   end.
   begin
   end;
end.

当文本为英文时,程序工作正常。 但是如果我把它改成俄语。它 returns 我们在控制台中使用问号。 针对俄语进行少量修改的代码。


var 
    x:integer;
    text:string;
    text_no_o:string;
begin
text:='Русский язык мой родной';
   for x := 0  to  Length(text) do
   //writeln(Ord(text[6]));
   if(Ord(text[x])=190) then    
   else
    text_no_o[x]:=text[x];
    write(text_no_o);
   end.
   begin
   end;
end.

我在控制台中收到的结果是:

Русский язык м�й р�дн�й

我希望收到

Русский язык мй рднй

因为我得到的问题可能是控制台中的编码设置不正确,所以我应该强制 pascal 使用 CP1252 而不是 ANSI。

我正在为 Linux 使用 Free Pascal 编译器版本 3.2.0+dfsg-12。 P.S 我不允许使用 StringReplace 或 Pos

简单的解决方案:

function Simple_StripO (Text : String) : String;
var 
  i : integer;
  Text2 : string;
begin
  Text2 := '';
  for i := 1 to Length(Text) do
    if Text[i] <> 'o' then
      Text2 := Text2 + Text[i];
  Result := Text2;  // Or Simple_StripO := Text2;
end; 

该字符串可能是 UTF8 编码的。所以西里尔字母 o 被编码为两个字符 $d0 $be。这里你替换了一个 $be (=190)。您需要替换两个字符,但不能只测试字符的值,因为它们的含义取决于周围的字符。

这是一种方法,记住当前状态(在字母之外或第一个字节之后)

var
  c: char;
  text: string;
  state: (sOutside, sAfterD0);
begin
  text:= 'Русский язык мой родной';
  state:= sOutside;
  for c in text do
  begin
    if state = sOutside then
    begin
      if c = #$D0 then // may be the start of the letter
        state := sAfterD0
      else
        write(c); // output this char because not part of letter
    end
    else if state = sAfterD0 then
    begin
      if c = #$BE then state := sOutside // finished skipping
      else
      begin
        // chars do not form letter so output skipped char
        write(#$D0, c);
        state := sOutside;
      end;
    end
  end;
  writeln;
end.