在 Pascal 中比较两个字符串的许多方法对我不起作用

Many ways of comparing two strings in pascal doesn't work for me

我在 Pascal 上做作业。除了尝试比较两个字符串以检查游戏是否完成之外,我几乎完成了所有事情。但是当我在 guess 过程中比较它们时,即使 encryption 字符串已经与 theWord 字符串相同,它也始终为假。我不太明白 Pascal 是如何处理字符串的。然后,我尝试在 main 中比较它们,输出 true。我真的很困惑。我试了SameStrCompareText=,结果都是一样的

代码:

program hangman;
Uses sysutils;

const 
    times = 6;

var
    theWordSize,i : integer;
    theWord,encryption : string;

function encrypt (): string;
var
    list : string;
begin
    for i := 1 to theWordSize do
        list[i] := '*';
    encrypt := list;
end;

procedure reveal(letter: char);
begin
    for i := 1 to theWordSize do
        if (theWord[i] = letter) then
            encryption[i] := theWord[i];
end;

procedure guess();
var
    letter : char;
    j : integer;
begin
    writeln('hello');
    j := times;
    while (j > 0) do
        begin
            writeln('Guess a letter( ':16, j:1, ' times left ): ':15);
            readln(letter);
            if pos(letter,theWord)<>0 then    // guess correctly
                begin
                    reveal(letter);
                    writeln('Correct! Word: ':15, encryption:7);
                    writeln(SameText(theWord,encryption));
                    if SameText(theWord,encryption) then
                    begin
                        writeln('You win!   The correct word: ':28, theWord:7);
                        exit
                    end;
                    inc(j)
                end
            else if (j > 1) then                // guess wrong
                writeln('Wrong!   Word: ':15, encryption:7)
            else
                writeln('You lose! The man is dead.   Correct Word: ':43, theWord:7);
            dec(j)
        end
end;

{* Main program: *}
begin
    theWord := 'mystery';
    theWordSize := byte(theWord[0]);
    //writeln(theWord[i]=='m');
    writeln('Weclome to Hangman game:');
    encryption := encrypt();
    writeln('Mystery Word: ':14, encryption:theWordSize);
    guess();
    for i := 0 to theWordSize do
        encryption[i] := theWord[i];
    writeln(SameText(theWord,encryption));
end.

部分 运行 结果:

Guess a letter( 6 times left ): 
e
Correct! Word: m*ste**
FALSE
Guess a letter( 6 times left ): 
r
Correct! Word: m*ster*
FALSE
Guess a letter( 6 times left ): 
y
Correct! Word: mystery
FALSE
Guess a letter( 6 times left ): 
a
Wrong!   Word: mystery
Guess a letter( 5 times left ): 
a
Wrong!   Word: mystery
Guess a letter( 4 times left ): 
a
Wrong!   Word: mystery
Guess a letter( 3 times left ): 
a
Wrong!   Word: mystery
Guess a letter( 2 times left ): 
a
Wrong!   Word: mystery
Guess a letter( 1 times left ): 
a
You lose! The man is dead.   Correct Word: mystery
TRUE

SO 有一种荣誉准则,即涉及作业时,我们不 只告诉你答案。因此,我将向您展示使用 Lazarus 的方法 调试器自己找出问题的原因。问题是,像 fpc 这样的编译器如果不能正确地进行字符串比较就不会存活很长时间,所以像 SameText 这样的函数失败的原因一定是因为你正在比较的字符串实际上并不相等。问题是 "why not?",找出调试的全部内容。

如果您还没有安装 Lazarus,请立即安装并在其中打开您的项目。如果, 第一次在其中编译 Hangman 时出现错误

Hangman.lpr(64,56) Error: Element zero of an ansi/wide- or longstring cannot be accessed, use (set)length instead

那是因为 Lazarus 假设您使用的是所谓的 "Huge strings",它 大小可达 2Gb,而您显然打算使用传统 Pascal "ShortStrings" 是最多 255 个字符的数组,前面有一个长度字节。

要强制 Lazarus 使用 ShortStrings,添加

$mode objfpc}{$H-}

就在`程序 Hangman 的下方。另外,当你在做的时候,改变

theWordSize := byte(theWord[0]);

theWordSize := Length(theWord);

因为不管 HugeStrings 还是 ShortStrings 都会起作用 没有关于字符串内部结构的假设。

下一步我要将设置 theWord 的行更改为

theWord := 'm'; //'mystery';

以尽量减少调试期间的输入量。然后,放一个调试器 行上的断点

    if SameText(theWord,encryption) then

通过在装订线的左边缘附近单击(具有源代码行号的区域 在里面)。

编译并运行程序,一旦控制台window出现,输入

mReturn

完成后,调试器将在断点处停止。按F8 单步执行调试器,您会发现它转到

inc(J);

很明显 SameText 失败了,这就是你用 q 进来的地方。毫无意义 继续使用当前的 运行 应用程序,因此请按 Ctrl-F7 终止它并重置调试器。

再次

运行 app,仔细看

行执行结果
writeln('Mystery Word: ':14, encryption:theWordSize);

你会注意到它没有显示任何值 encryption。这是出了什么问题的重要线索。 'm'你 输入没有错,所以 encryption 不能有相同的值。唯一的 剩下要做的就是找出它实际具有的价值。请注意 如果您尝试使用 F7 计算 encryption,它会显示空白, 不是您期望的星号。

下一位,在行上打断点

for i := 1 to theWordSize do

encrypt函数中,将代码window拖到屏幕右侧。然后,按 打开Watches window,如有必要,将其拖入space,通过移动代码window释放,并在其中输入以下表达式

list[0]

list[1]

这是为了让您能够观察到列表的长度字节和第一个字符中的值。 运行 应用程序直到 encrypte 断点,然后单步绕过 for 循环。你会发现

的值
list[0]

不会改变,即使 list[1] 的值已设置为 'm'。

所以,encrypt返回的是一个空字符串,QED,我相信你会意识到 如何修复它。对不起,如果这已经相当累人,但至少它应该 让您了解如何系统地调试您 运行 遇到的下一个问题。