Modula-2 でプログラミング -- 文字列探索プログラム find の製作 (その2)
2024-12-28


BasicFileIO モジュール、StdFileIO モジュールをつかった find プログラムは、以下のとおりです。

MODULE Find;
FROM InOut IMPORT Write,WriteCard,WriteString,WriteLn;
FROM Files IMPORT FILE,FileState,Open,Close,Read;
FROM CmdArgs IMPORT Argc,Argv;
FROM FileSearch IMPORT pFileList,FileNameNode,MakeFileList;
FROM BasicFileIO IMPORT FileIOStruct,pFileIOStruct,
        OpenFile,CloseFile,EOFFile,FileIOStatus;
FROM StdFileIO IMPORT GetLine;

CONST
        EOS = 0C;
        MAXLINE = 128;
        FILENAMESIZE = 14;
        EOFMARK = 32C;

VAR
        FileMatch: ARRAY [0..FILENAMESIZE] OF CHAR;
        Target: ARRAY [0..MAXLINE] OF CHAR;
        CPos,FileNumber,LineNumber,nArgc: CARDINAL;
        pList: pFileList;

PROCEDURE putLine(FileName:ARRAY OF CHAR;Line:CARDINAL;
                Buffer: ARRAY OF CHAR);
BEGIN
        WriteString(FileName);
        Write(' ');WriteCard(Line,1);Write(':');
        WriteString(Buffer);
        WriteLn
END putLine;

PROCEDURE findTarget(Target,Line:ARRAY OF CHAR): BOOLEAN;
VAR
        t,l: CARDINAL;
        found: BOOLEAN;
BEGIN
        found := FALSE;
        t := 0; l := 0;
        WHILE (Line[l] # EOS) AND (NOT found) DO
                IF Line[l] = Target[0] THEN
                        t := 1;
                        WHILE Line[l+t] = Target[t] DO
                                INC(t);
                        END;
                        IF Target[t] = EOS THEN
                                found := TRUE;
                        END;
                END;
                INC(l);
        END;
        RETURN found
END findTarget;

PROCEDURE Usage();
BEGIN
        WriteString('find');WriteLn;
        WriteString('      TargetString File1 File2 FIle3,,,,');WriteLn 
END Usage;

PROCEDURE MatchLines(FileName,TargetString: ARRAY OF CHAR);
VAR
        pFileIO: pFileIOStruct;
        Line: ARRAY [0..MAXLINE-1] OF CHAR;
        Chars: CARDINAL;
        NLines: CARDINAL;
        Junk: FileIOStatus;

BEGIN
        IF OpenFile(FileName,pFileIO) = Success THEN
                NLines := 1;
                WHILE NOT EOFFile(pFileIO) DO
                        Chars := GetLine(pFileIO,Line);
                        IF findTarget(TargetString,Line) THEN
                                putLine(FileName,NLines,Line);
                        END;
                        INC(NLines);
                END;
                Junk := CloseFile(pFileIO)
        END
END MatchLines;

BEGIN
        nArgc := Argc();
        IF nArgc < 1 THEN
                Usage();
                HALT
        END;
        Argv(0,Target);
        FileNumber := 1;
        WHILE FileNumber < nArgc DO
                Argv(FileNumber,FileMatch);
                pList := MakeFileList(FileMatch);
                WHILE pList # NIL DO
                        MatchLines(pList^.FileName,Target);
                        pList := pList^.Next
                END;
                INC(FileNumber)
        END
END Find.

MachLine で、指定された文字列が読み込んだ行に存在するかを検査し、存在したら書き出します。

ファイル名のリスト構造が丸見えなのでひと工夫する必要がありますが、今回は見送りました。


コメント(全0件)
コメントをする


記事を書く
powered by ASAHIネット