You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pascal中While循环检测EOF时无法退出的问题排查

Pascal读取文件时EOF识别失败问题解决

问题描述

需要读取input.txt中的字符序列,按规则转换后输出到salida.txt,但程序中的While循环无法正确识别EOF,导致无法正常退出,最终输出大量无效的@字符。

现有代码

program LaboratorioPascal;
uses crt;
var 
    sec, sal: Textfile;
    v: char;
    por_especial, cont_palabra, cont_caracter, cont_especial: integer; 
    vocales2: set of char;
    pares: set of char;
    impares: set of char;
    consonantes: set of char;
    consonantes2: set of char;

    procedure numeros(var x: char);
    begin 
        case x of
            '0': Write(sal, '0');
            '1': Write(sal, '1');
            '2': Write(sal, '4');
            '3': begin 
                     Write(sal, '2'); 
                     Write(sal, '7');
                 end;
            '4': Write(sal, '8');
            '5': begin
                     Write(sal, '1'); 
                     Write(sal, '2'); 
                     Write(sal, '5');
                 end; 
            '6': begin
                     Write(sal, '1');
                     Write(sal, '2');
                 end; 
            '7': begin
                     Write(sal, '3'); 
                     Write(sal, '4'); 
                     Write(sal, '3');
                 end;
            '8': begin
                     Write(sal, '1'); 
                     Write(sal, '6');
                 end;
            '9': begin
                     Write(sal, '7');
                     Write(sal, '2'); 
                     Write(sal, '9');
                 end;
            else Exit;
        end;
    end;

    function vocales(var s: char): char;
    begin
        case s of 
            'e': vocales := 'u';
            'a': vocales := 'o';
            'i': vocales := 'a';
            'o': vocales := 'e';
            else vocales := 'i';
        end;
    end;

begin
    assign(sec, 'input.txt');   // Le asignamos un archivo del cual lea
    reset(sec);                 // arrancamos la secuencia
    read(sec, v);               // leemos la secuencia. avz(sec, v)
    assign(sal, 'salida.txt');
    rewrite(sal);
    vocales2 := ['a', 'e', 'i', 'o', 'u'];
    pares :=  ['0', '2', '4', '6', '8'];
    impares :=  ['1', '3', '5', '7', '9'];
    consonantes := ['b', 'c', 'd', 'f', 'g', 'h', 'j','k','l','m', 'n'];
    consonantes2 := ['p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z'];
    por_especial := 0;
    cont_palabra := 0;
    cont_caracter := 0;
    cont_especial := 0;
    writeln('El objetivo de este programa es cifrar un mensaje para favorecer a la inteligencia Rusa.');

    while not eof(sec) do 
    begin
        while v = ' ' do 
        begin
            write(sal, ' ');
            read(sec, v);
        end;

        cont_palabra := cont_palabra + 1;

        while v <> ' ' do
        begin
            if (v in consonantes) or (v in consonantes2) then 
            begin
                write(sal, '1');
            end
            else
            begin
                if v in vocales2 then
                begin
                    Write(sal, vocales(v));
                end
                else
                begin
                    if v in pares then;
                    begin
                        numeros(v);
                    end;

                    begin
                        if v in impares then
                        begin
                            numeros(v);
                        end
                        else
                        begin
                            cont_especial := cont_especial + 1;
                            Write(sal, '@');
                        end;
                    end;
                end;
            end;

            read(sec, v);
        end;
    end;

    write(cont_palabra, ' se crifraon con [Exito]');
    
    close(sec);
    close(sal);
end.

当前输出(salida.txt)

1o1ao i1o 1u1 i1 1e1111ie 1iu 1u 1e1ae o i1o 11a11u1o@@@ 1a1@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

已尝试的操作

查阅EOF相关资料但未找到Pascal相关内容;尝试在循环内添加if eof then Exit;,但程序仅能读取一个字符,问题未解决。


问题根源

  1. 初始读取未做EOF检查:程序开头直接执行read(sec, v),若input.txt为空会直接报错;且外层循环依赖eof(sec)判断,但内层循环在到达EOF后仍会继续处理v的旧值,导致无限写入@。
  2. 语法错误导致逻辑混乱:if v in pares then;末尾多了分号,使得后续的numeros(v)调用无条件执行,同时后续的奇偶判断也会重复执行,逻辑冲突。
  3. 内层循环未处理EOF:在内层while v <> ' '循环中,读取字符后未检查是否到达EOF,导致EOF后仍进入循环体处理无效字符。

修复方案

program LaboratorioPascal;
uses crt;
var 
    sec, sal: Textfile;
    v: char;
    cont_palabra, cont_especial: integer; 
    vocales2: set of char;
    pares: set of char;
    impares: set of char;
    consonantes: set of char;

    procedure numeros(x: char);
    begin 
        case x of
            '0': Write(sal, '0');
            '1': Write(sal, '1');
            '2': Write(sal, '4');
            '3': begin 
                     Write(sal, '2'); 
                     Write(sal, '7');
                 end;
            '4': Write(sal, '8');
            '5': begin
                     Write(sal, '1'); 
                     Write(sal, '2'); 
                     Write(sal, '5');
                 end; 
            '6': begin
                     Write(sal, '1');
                     Write(sal, '2');
                 end; 
            '7': begin
                     Write(sal, '3'); 
                     Write(sal, '4'); 
                     Write(sal, '3');
                 end;
            '8': begin
                     Write(sal, '1'); 
                     Write(sal, '6');
                 end;
            '9': begin
                     Write(sal, '7');
                     Write(sal, '2'); 
                     Write(sal, '9');
                 end;
            else Exit;
        end;
    end;

    function vocales(s: char): char;
    begin
        case s of 
            'e': vocales := 'u';
            'a': vocales := 'o';
            'i': vocales := 'a';
            'o': vocales := 'e';
            'u': vocales := 'i';
            else vocales := 'i';
        end;
    end;

begin
    assign(sec, 'input.txt');
    reset(sec);
    assign(sal, 'salida.txt');
    rewrite(sal);
    
    vocales2 := ['a', 'e', 'i', 'o', 'u'];
    pares :=  ['0', '2', '4', '6', '8'];
    impares :=  ['1', '3', '5', '7', '9'];
    consonantes := ['b', 'c', 'd', 'f', 'g', 'h', 'j','k','l','m', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z'];
    
    cont_palabra := 0;
    cont_especial := 0;
    writeln('El objetivo de este programa es cifrar un mensaje para favorecer a la inteligencia Rusa.');

    while not eof(sec) do 
    begin
        read(sec, v);
        
        while not eof(sec) and (v = ' ') do 
        begin
            write(sal, ' ');
            read(sec, v);
        end;
        
        if eof(sec) then break;
        
        cont_palabra := cont_palabra + 1;

        while not eof(sec) and (v <> ' ') do
        begin
            if v in consonantes then 
            begin
                write(sal, '1');
            end
            else if v in vocales2 then
            begin
                Write(sal, vocales(v));
            end
            else if (v in pares) or (v in impares) then
            begin
                numeros(v);
            end
            else
            begin
                cont_especial := cont_especial + 1;
                Write(sal, '@');
            end;

            if not eof(sec) then read(sec, v);
        end;
    end;

    writeln(cont_palabra, ' se cifraron con [Exito]');
    
    close(sec);
    close(sal);
end.

修复要点说明

  • 调整读取逻辑:将初始读取移到外层循环内,每次循环先读取字符,再进行判断,避免初始读取空文件的问题。
  • 添加EOF检查:所有内层循环和读取操作前都添加not eof(sec)判断,确保到达EOF时及时退出循环。
  • 修复语法错误:删除if v in pares then;的多余分号,合并辅音集合简化判断,修正拼写错误crifraon为cifraron。
  • 优化参数传递:numeros和vocales函数无需使用var参数,因为仅读取字符值,不修改原变量。

内容的提问来源于stack exchange,提问作者Facundo Blanco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 16:48:35