{ INTOOLS  -  Procedures and Functions for interactive input in Pascal  Copyright (c) 1984 by Ronald Florence      These procedures and functions were written to avoid the horrors of  "Data Format Error in file USER" crashes. The procedures will work  with IBM Pascal or MS-Pascal, and can be incorporately separately as  needed with {$include} metacommands.     RDREAL: reads a real number (positive or negative) in decimal format    RDINT: reads an integer (positive or negative) within a specified range    RDCHAR: reads a character in a specified set  (inkey)    NOMORE: prompts the user with 'More?' and reads a 'y' or 'n' (inkey)    YESNO: reads a 'y' or 'n' (inkey)  Use the tools in 'repeat...until' loops. For example:      repeat          write ('Enter an integer between 0 and 10: ');      until rdint(0,10);  Include 'charset = set of char' as a type declaration when using RDCHAR    }function rdreal (var  r: real): boolean;    const    bell = chr (7);    var   decimal, left, right: real;          neg: boolean;begin    left:= 0;    decimal:= 1;    right:= 0;    neg:= false;    while not eoln and not (input^ in [chr(33)..chr(255)]) do get (input);    neg:= input^ = chr(45);    if neg then get (input);    rdreal:= input^ in ['0'..'9'];    while input^ in ['0'..'9'] do begin;        left:= left * 10 + ord (input^) - ord ('0');        get (input);    end;    if input^ = chr(46) then begin        get (input);        while input^ in ['0'..'9'] do begin            right:= right + decimal * (ord (input^) - ord ('0')) / 10;            decimal:= decimal / 10;            get (input);        end;    end;    r:= left + right;    if neg then r:= - r;    if input^ in [chr(33)..chr(44), chr(47), chr(58)..chr(255)] then begin        rdreal:= false;        write (bell);    end;    readln;end;function rdint (var  i:integer; low,high:integer): boolean;    const   bell = chr (7);    var   neg: boolean;begin    i:= 0;    neg:= false;    while not eoln and not (input^ in [chr(33)..chr(255)]) do get (input);    neg:= input^ = chr(45);    if neg then get (input);    while input^ in ['0'..'9'] do begin        i:= i * 10 + ord (input^) - ord ('0');        get (input);    end;    if neg then i:= - i;    if (input^ in [chr(33)..chr(44), chr(46), chr(47), chr(58)..chr(255)]) or        (eoln and ((i < low) or (i > high))) then begin            rdint:= false;            write (bell);    end    else rdint:= (i >= low) and (i <= high);    readln;end;function rdchar (okchars: charset): char;var   f, g: file of char;      c: char;function inkey: char;    begin        repeat get (f) until f^ <> chr (0);        inkey:= f^;    end;begin    assign (f, 'user');    reset (f);    assign (g, 'user');    rewrite (g);    repeat        c:= inkey;        if not (c in okchars) then if c in ['A'..'Z'] then            c:= chr (ord(c) - ord('A') + ord('a'))        else if c in ['a'..'z'] then c:= chr (ord(c) - ord('a') + ord('A'));    until c in okchars;    write (g, c);    writeln;    rdchar:= c;end;function nomore: boolean;var   f, g: file of char;      c: char;function inkey: char;    begin        repeat get (f) until f^ <> chr (0);        inkey:= f^;    end;begin    write ('More? ');    assign (f, 'user');    reset (f);    assign (g, 'user');    rewrite (g);    repeat c:= inkey until c in ['y','Y','n','N'];    write (g, c);    writeln;    nomore:= c in ['n', 'N']end;function yes: boolean;var   f, g: file of char;      c: char;function inkey: char;    begin        repeat get (f) until f^ <> chr (0);        inkey:= f^;    end;begin    assign (f, 'user');    reset (f);    assign (g, 'user');    rewrite (g);    repeat c:= inkey until c in ['y','Y','n','N'];    write (g,c);    writeln;    yes:= c in ['y', 'Y'];end; rewrite (g);    repeat c:= inkey until c in ['y','Y','n','N'];    write (g,c);    writel