Input loop

Revision as of 15:58, 21 March 2020 by Thundergnat (talk | contribs) (Fix Perl 6 -> Raku in comments)

Read from a text stream either word-by-word or line-by-line until the stream runs out of data.

Task
Input loop
You are encouraged to solve this task according to the task description, using any language you may know.
Input loop is part of Short Circuit's Console Program Basics selection.
Task

The stream will have an unknown amount of data on it.

AArch64 Assembly

Works with: as version Raspberry Pi 3B version Buster 64 bits

<lang AArch64 Assembly> /* ARM assembly AARCH64 Raspberry PI 3B */ /* program inputLoop64.s */

/*******************************************/ /* Constantes file */ /*******************************************/ /* for this file see task include a file in language AArch64 assembly*/ .include "../includeConstantesARM64.inc"

.equ BUFSIZE, 10000 .equ LINESIZE, 100

/*********************************/ /* Initialized data */ /*********************************/ .data szMessErreur: .asciz "Erreur ouverture fichier input.\n" szMessErreur1: .asciz "Erreur fermeture fichier.\n" szMessErreur2: .asciz "Erreur lecture fichier.\n" szCarriageReturn: .asciz "\n" szMessEndLine: .asciz "<<<<<< End line.\n"

szMessCodeErr: .asciz "Error code décimal : @ \n"

szNameFileInput: .asciz "input.txt"

/*******************************************/ /* DONNEES NON INITIALISEES */ /*******************************************/ .bss sZoneConv: .skip 24 sBuffer: .skip BUFSIZE sBufferWord: .skip LINESIZE /**********************************************/ /* -- Code section */ /**********************************************/ .text .global main main:

   /* open file */
   mov x0,AT_FDCWD
   ldr x1,qAdrszNameFileInput     // file name
   mov x2,O_RDONLY                //  flags   
   mov x3,0                       // mode 
   mov x8,OPEN                    // call system OPEN
   svc 0 
   cmp x0,0                       // open error ?
   ble erreur
   /* read file  */
   mov x9,x0                      // save File Descriptor
   ldr x1,qAdrsBuffer             // buffer address 
   mov x2,BUFSIZE                 // buffer size
   mov x8,READ                    // call system  READ
   svc 0 
   cmp x0,0                       // read error ?
   ble erreur2
   mov x2,x0                      // length read characters
   /* buffer analyze   */
   ldr x3,qAdrsBuffer             // buffer address
   ldr x5,qAdrsBufferWord         // buffer address
   mov x7,0                       // word byte counter
   mov x4,0                       // byte counter
   mov x10,1

1:

   ldrb w6,[x3,x4]                // load byte buffer
   cmp x6,' '                     // space ?
   csel x8,xzr,x10,eq             // yes  0-> x8
   beq 2f
   cmp x6,0xA                     // end line ?
   csel x8,x10,xzr,eq             // yes 1 -> x8
   beq 2f
   cmp x6,0xD                     // end line ?
   csel x8,x10,xzr,eq
   beq 3f
   strb w6,[x5,x7]                // store byte
   add x7,x7,1                    // increment word byte counter
   b 4f

2: // word end

   cmp x7,0
   beq 3f
   mov x6,0                       // store 0 final
   strb w6,[x5,x7]
   mov x0,x5                      // display word
   bl affichageMess
   ldr x0,qAdrszCarriageReturn
   bl affichageMess
   mov x7,0                       // raz word byte counter 

3:

   cmp x8,1                       // end line ?
   bne 4f
   ldr x0,qAdrszMessEndLine
   bl affichageMess

4:

   add x4,x4,1                    // increment read buffer counter
   cmp x4,x2                      // end bytes ?
   blt 1b                         // no -> loop 

4:

   /* close imput file */
   mov x0,x9                      // Fd
   mov x8,CLOSE                   // call system CLOSE
   svc 0 
   cmp x0,0                       // close error ?
   blt erreur1
   mov x0,0                       // return code OK
   b 100f

erreur:

   ldr x1,qAdrszMessErreur 
   bl displayError
   mov x0,1                       // error return code
   b 100f

erreur1:

   ldr x1,qAdrszMessErreur1   
   bl displayError
   mov x0,1                      // error return code
   b 100f

erreur2:

   ldr x1,qAdrszMessErreur2   
   bl displayError
   mov x0,1                      // error return code
   b 100f

100: // end program

   mov x8,EXIT
   svc 0 

qAdrszNameFileInput: .quad szNameFileInput qAdrszMessErreur: .quad szMessErreur qAdrszMessErreur1: .quad szMessErreur1 qAdrszMessErreur2: .quad szMessErreur2 qAdrszCarriageReturn: .quad szCarriageReturn qAdrszMessEndLine: .quad szMessEndLine qAdrsBuffer: .quad sBuffer qAdrsBufferWord: .quad sBufferWord /******************************************************************/ /* display error message */ /******************************************************************/ /* x0 contains error code */ /* x1 contains address error message */ displayError:

   stp x2,lr,[sp,-16]!            // save  registers
   mov x2,x0                      // save error code
   mov x0,x1                      // display message error
   bl affichageMess
   mov x0,x2
   ldr x1,qAdrsZoneConv           // conversion error code
   bl conversion10S               // decimal conversion
   ldr x0,qAdrszMessCodeErr
   ldr x1,qAdrsZoneConv
   bl strInsertAtCharInc          // insert result at @ character
   bl affichageMess               // display message final
   ldp x2,lr,[sp],16              // restaur  2 registers
   ret                            // return to address lr x30

qAdrsZoneConv: .quad sZoneConv qAdrszMessCodeErr: .quad szMessCodeErr /********************************************************/ /* File Include fonctions */ /********************************************************/ /* for this file see task include a file in language AArch64 assembly */ .include "../includeARM64.inc" </lang>

Ada

This example reads in a text stream from standard input line by line and writes the output to standard output. <lang ada>with Ada.Text_Io; use Ada.Text_Io;

procedure Read_Stream is

  Line : String(1..10);
  Length : Natural;

begin

  while not End_Of_File loop
     Get_Line(Line, Length); -- read up to 10 characters at a time
     Put(Line(1..Length));
     -- The current line of input data may be longer than the string receiving the data.
     -- If so, the current input file column number will be greater than 0
     -- and the extra data will be unread until the next iteration.
     -- If not, we have read past an end of line marker and col will be 1
     if Col(Current_Input) = 1 then
        New_Line;
     end if;
  end loop;

end Read_Stream;</lang>

Aime

<lang aime>void read_stream(file f) {

   text s;
   while (f_line(f, s) != -1) {
       # the read line available as -s-
   }

}</lang>

ALGOL 68

For file consisting of just one page - a typical linux/unix file: <lang algol68>main:(

 PROC raise logical file end = (REF FILE f) BOOL: ( except logical file end );
 on logical file end(stand in, raise logical file end);
 DO
   print(read string);
   read(new line);
   print(new line)
 OD;
 except logical file end: 
   SKIP

)</lang> For multi page files, each page is seekable with PROC set = (REF FILE file, INT page, line, char)VOID: ~. This allows rudimentary random access where each new page is effectively a new record. <lang algol68>main:(

 PROC raise logical file end = (REF FILE f) BOOL: ( except logical file end );
 on logical file end(stand in, raise logical file end);
 DO
   PROC raise page end = (REF FILE f) BOOL: ( except page end );
   on page end(stand in, raise page end);
   DO
     print(read string);
     read(new line);
     print(new line)
   OD;
   except page end: 
     read(new page);
     print(new page)
 OD;
 except logical file end: 
   SKIP

)</lang> The boolean functions physical file ended(f), logical file ended(f), page ended(f) and line ended(f) are also available to indicate the end of a file, page and line.

ALGOL W

<lang algolw>begin

   string(80) line;
   % allow the program to continue after reaching end-of-file %
   % without this, end-of-file would cause a run-time error   %
   ENDFILE := EXCEPTION( false, 1, 0, false, "EOF" );
   % read lines until end of file                             %
   read( line );
   while not XCPNOTED(ENDFILE) do begin
       write( line );
       read(  line )
   end        

end.</lang>

AmigaE

<lang amigae>CONST BUFLEN=1024, EOF=-1

PROC consume_input(fh)

 DEF buf[BUFLEN] : STRING, r
 REPEAT
   /* even if the line si longer than BUFLEN,
      ReadStr won't overflow; rather the line is
      "splitted" and the remaining part is read in
      the next ReadStr */
   r := ReadStr(fh, buf)
   IF buf[] OR (r <> EOF)
     -> do something
     WriteF('\s\n',buf)
   ENDIF
 UNTIL r=EOF

ENDPROC

PROC main()

 DEF fh
 fh := Open('basicinputloop.e', OLDFILE)
 IF fh
   consume_input(fh)
   Close(fh)
 ENDIF

ENDPROC</lang>

ARM Assembly

Works with: as version Raspberry Pi

<lang ARM Assembly>

/* ARM assembly Raspberry PI */ /* program inputLoop.s */

/* REMARK 1 : this program use routines in a include file

  see task Include a file language arm assembly 
  for the routine affichageMess conversion10 
  see at end of this program the instruction include */

/*********************************************/ /*constantes */ /********************************************/ .equ STDOUT, 1 @ Linux output console .equ EXIT, 1 @ Linux syscall .equ READ, 3 .equ WRITE, 4 .equ OPEN, 5 .equ CLOSE, 6 .equ CREATE, 8 /* file */ .equ O_RDONLY, 0x0 @ open for reading only

.equ BUFSIZE, 10000 .equ LINESIZE, 100

/*********************************/ /* Initialized data */ /*********************************/ .data szMessErreur: .asciz "Erreur ouverture fichier input.\n" szMessErreur1: .asciz "Erreur fermeture fichier.\n" szMessErreur2: .asciz "Erreur lecture fichier.\n" szCarriageReturn: .asciz "\n" szMessEndLine: .asciz "<<<<<< End line.\n"

szNameFileInput: .asciz "input.txt"

/*******************************************/ /* DONNEES NON INITIALISEES */ /*******************************************/ .bss sBuffer: .skip BUFSIZE sBufferWord: .skip LINESIZE /**********************************************/ /* -- Code section */ /**********************************************/ .text .global main main:

   /* open file */
   ldr r0,iAdrszNameFileInput      @ file name
   mov r1,#O_RDONLY                @  flags   
   mov r2,#0                       @ mode 
   mov r7,#OPEN                    @ call system OPEN
   svc #0 
   cmp r0,#0                       @ open error ?
   ble erreur
   /* read file  */
   mov r9,r0                       @ save File Descriptor
   ldr r1,iAdrsBuffer              @ buffer address 
   mov r2,#BUFSIZE                 @ buffer size
   mov r7, #READ                   @ call system  READ
   svc 0 
   cmp r0,#0                       @ read error ?
   ble erreur2
   mov r2,r0                       @ length read characters
   /* buffer analyze   */
   ldr r3,iAdrsBuffer              @ buffer address
   ldr r5,iAdrsBufferWord          @ buffer address
   mov r7,#0                       @ word byte counter
   mov r4,#0                       @ byte counter

1:

   ldrb r6,[r3,r4]                 @ load byte buffer
   cmp r6,#' '                     @ space ?
   moveq r8,#0                     @ yes
   beq 2f
   cmp r6,#0xA                     @ end line ?
   moveq r8,#1
   beq 2f
   cmp r6,#0xD                     @ end line ?
   beq 3f
   strb r6,[r5,r7]                 @ store byte
   add r7,#1                       @ increment word byte counter
   b 4f

2: @ word end

   cmp r7,#0
   beq 3f
   mov r6,#0                       @ store 0 final
   strb r6,[r5,r7]
   mov r0,r5                       @ display word
   bl affichageMess
   ldr r0,iAdrszCarriageReturn
   bl affichageMess
   mov r7,#0                       @ raz word byte counter 

3:

   cmp r8,#1                       @ end line ?
   bne 4f
   ldr r0,iAdrszMessEndLine
   bl affichageMess

4:

   add r4,#1                       @ increment read buffer counter
   cmp r4,r2                       @ end bytes ?
   blt 1b                          @ no -> loop 

4:

   /* close imput file */
   mov r0,r9                       @ Fd
   mov r7, #CLOSE                  @ call system CLOSE
   svc 0 
   cmp r0,#0                       @ close error ?
   blt erreur1


   mov r0,#0     @ return code OK
   b 100f

erreur:

   ldr r1,iAdrszMessErreur 
   bl displayError
   mov r0,#1       @ error return code
   b 100f

erreur1:

   ldr r1,iAdrszMessErreur1   
   bl displayError
   mov r0,#1       @ error return code
   b 100f

erreur2:

   ldr r1,iAdrszMessErreur2   
   bl displayError
   mov r0,#1       @ error return code
   b 100f


100: @ end program

   mov r7, #EXIT 
   svc 0 

iAdrszNameFileInput: .int szNameFileInput iAdrszMessErreur: .int szMessErreur iAdrszMessErreur1: .int szMessErreur1 iAdrszMessErreur2: .int szMessErreur2 iAdrszCarriageReturn: .int szCarriageReturn iAdrszMessEndLine: .int szMessEndLine iAdrsBuffer: .int sBuffer iAdrsBufferWord: .int sBufferWord /***************************************************/ /* ROUTINES INCLUDE */ /***************************************************/ .include "../affichage.inc" </lang>

Output:
word1
word2
word3
<<<<<< End line.
Line2w1
line2w2
<<<<<< End line.
Oneword
<<<<<< End line.
<<<<<< End line.
AfterEmptyLine
<<<<<< End line.

AutoHotkey

This example reads the text of a source file line by line and writes the output to a destination file. <lang AutoHotkey>Loop, Read, Input.txt, Output.txt {

  FileAppend, %A_LoopReadLine%`n

}</lang>

AWK

This just reads lines from stdin and prints them until EOF is read.

<lang awk>{ print $0 }</lang>

or, more idiomatic:

<lang awk>1</lang>

BASIC

Applesoft BASIC

<lang ApplesoftBasic>100 INPUT "FILENAME:";F$ 110 D$ = CHR$(4) 120 PRINT D$"VERIFY"F$ 130 PRINT D$"OPEN"F$ 140 PRINT D$"READ"F$ 150 ONERR GOTO 190

160 GET C$ 170 PRINT CHR$(0)C$; 180 GOTO 160

190 POKE 216,0 200 IF PEEK(222) <> 5 THEN RESUME 210 PRINT D$"CLOSE"F$</lang>

BBC BASIC

This specifically relates to console input (stdin). <lang bbcbasic> STD_INPUT_HANDLE = -10

     STD_OUTPUT_HANDLE = -11
     SYS "GetStdHandle", STD_INPUT_HANDLE TO @hfile%(1)
     SYS "GetStdHandle", STD_OUTPUT_HANDLE TO @hfile%(2)
     SYS "SetConsoleMode", @hfile%(1), 0
     *INPUT 13
     *OUTPUT 14
     REPEAT
       INPUT A$
       PRINT A$
     UNTIL FALSE</lang>

IS-BASIC

<lang IS-BASIC>100 PROGRAM "Type.bas" 110 TEXT 80 120 INPUT PROMPT "File name: ":F$ 130 WHEN EXCEPTION USE IOERROR 140 OPEN #1:F$ ACCESS INPUT 150 DO 160 LINE INPUT #1,IF MISSING EXIT DO:F$ 170 PRINT F$ 180 LOOP 190 CLOSE #1 200 END WHEN 210 HANDLER IOERROR 220 PRINT EXSTRING$(EXTYPE) 230 END 240 END HANDLER</lang>

Alternate solution: <lang IS-BASIC>100 PROGRAM "Type.bas" 110 INPUT PROMPT "File name: ":F$ 120 WHEN EXCEPTION USE IOERROR 130 OPEN #1:F$ 140 COPY FROM #1 TO #0 150 CLOSE #1 160 END WHEN 170 HANDLER IOERROR 180 PRINT EXSTRING$(EXTYPE) 190 CLOSE #1 200 END HANDLER</lang>

Batch File

<lang dos> for /f %%i in (file.txt) do if %%i@ neq @ echo %%i </lang>

Bracmat

This example first creates a test file with three lines. It then opens the file in read mode, sets the string of break characters and then reads the file token by token, where tokens are delimeted by break characters. Finally, the file position is set to an invalid value, which closes the file. <lang bracmat>( put$("This is a three line text","test.txt",NEW) & fil$("test.txt",r) & fil$(,STR," \t\r\n") & 0:?linenr & whl

 ' ( fil$:(?line.?breakchar)
   &   put
     $ ( str
       $ ( "breakchar:"
           ( !breakchar:" "&SP
           | !breakchar:\t&"\\t"
           | !breakchar:\r&"\\r"
           | !breakchar:\n&"\\n"
           | !breakchar:&EOF
           )
           ", word "
           (1+!linenr:?linenr)
           ":"
           !line
           \n
         )
       )
   )

& (fil$(,SET,-1)|out$"file closed") );</lang>

Output:
breakchar:SP, word 1:This
breakchar:\n, word 2:is
breakchar:SP, word 3:a
breakchar:SP, word 4:three
breakchar:\n, word 5:line
breakchar:EOF, word 6:text
file closed

C

Reads arbitrarily long line each time and return a null-terminated string. Caller is responsible for freeing the string. <lang c>#include <stdlib.h>

  1. include <stdio.h>

char *get_line(FILE* fp) { int len = 0, got = 0, c; char *buf = 0;

while ((c = fgetc(fp)) != EOF) { if (got + 1 >= len) { len *= 2; if (len < 4) len = 4; buf = realloc(buf, len); } buf[got++] = c; if (c == '\n') break; } if (c == EOF && !got) return 0;

buf[got++] = '\0'; return buf; }

int main() { char *s; while ((s = get_line(stdin))) { printf("%s",s); free(s); } return 0; }</lang>

C#

<lang csharp>using System; using System.IO;

class Program {

   static void Main(string[] args)
   {
       // For stdin, you could use
       // new StreamReader(Console.OpenStandardInput(), Console.InputEncoding)
       using (var b = new StreamReader("file.txt"))
       {
           string line;
           while ((line = b.ReadLine()) != null)
               Console.WriteLine(line);
       }
   }

}</lang>

C++

The following functions send the words resp. lines to a generic output iterator. <lang cpp>

  1. include <istream>
  2. include <string>
  3. include <vector>
  4. include <algorithm>
  5. include <iostream>
  6. include <iterator>

// word by word template<class OutIt> void read_words(std::istream& is, OutIt dest) {

 std::string word;
 while (is >> word)
 {
   // send the word to the output iterator
   *dest = word;
 }

}

// line by line: template<class OutIt> void read_lines(std::istream& is, OutIt dest) {

 std::string line;
 while (std::getline(is, line))
 {
   // store the line to the output iterator
   *dest = line;
 }

}

int main() {

 // 1) sending words from std. in std. out (end with Return)
 read_words(std::cin, 
            std::ostream_iterator<std::string>(std::cout, " "));
 // 2) appending lines from std. to vector (end with Ctrl+Z)
 std::vector<std::string> v;
 read_lines(std::cin, std::back_inserter(v));
 
 return 0;

}

</lang>

An alternate way to read words or lines is to use istream iterators:

<lang cpp> template<class OutIt> void read_words(std::istream& is, OutIt dest) {

   typedef std::istream_iterator<std::string> InIt;
   std::copy(InIt(is), InIt(),
             dest);

}

namespace detail {

   struct ReadableLine : public std::string 
   { 
       friend std::istream & operator>>(std::istream & is, ReadableLine & line)
       {   
           return std::getline(is, line);
       }
   };

}

template<class OutIt> void read_lines(std::istream& is, OutIt dest) {

   typedef std::istream_iterator<detail::ReadableLine> InIt;
   std::copy(InIt(is), InIt(),
             dest);

} </lang>

Clojure

<lang lisp>(defn basic-input [fname]

 (line-seq (java.io.BufferedReader. (java.io.FileReader. fname))))</lang>

COBOL

Works with: GNU Cobol version 2.0
Works with: Visual COBOL

<lang cobol> IDENTIFICATION DIVISION.

      PROGRAM-ID. input-loop.
      
      ENVIRONMENT DIVISION.
      INPUT-OUTPUT SECTION.
      FILE-CONTROL.
          SELECT in-stream ASSIGN TO KEYBOARD *> or any other file/stream
              ORGANIZATION LINE SEQUENTIAL
              FILE STATUS in-stream-status.
              
      DATA DIVISION.
      FILE SECTION.
      FD  in-stream.
      01  stream-line                 PIC X(80).
      
      WORKING-STORAGE SECTION.
      01  in-stream-status            PIC 99.
          88  end-of-stream           VALUE 10.
      
      PROCEDURE DIVISION.
          OPEN INPUT in-stream
          
          PERFORM UNTIL EXIT
              READ in-stream
                  AT END
                      EXIT PERFORM
              END-READ
              DISPLAY stream-line
          END-PERFORM
          
          CLOSE in-stream
          .
      END PROGRAM input-loop.</lang>

Common Lisp

<lang lisp>(defun basic-input (filename)

   (with-open-file (stream (make-pathname :name filename) :direction :input)
       (loop for line = (read-line stream nil nil)
           while line
           do (format t "~a~%" line))))</lang>

D

<lang d>void main() {

   import std.stdio;
   immutable fileName = "input_loop1.d";
   foreach (const line; fileName.File.byLine) {
       pragma(msg, typeof(line)); // Prints: const(char[])
       // line is a transient slice, so if you need to
       // retain it for later use, you have to .dup or .idup it.
       line.writeln; // Do something with each line.
   }
   // Keeping the line terminators:
   foreach (const line; fileName.File.byLine(KeepTerminator.yes)) {
       // line is a transient slice.
       line.writeln;
   }
   foreach (const string line; fileName.File.lines) {
       // line is a transient slice.
       line.writeln;
   }

}</lang>

Library: Tango

<lang d>import tango.io.Console; import tango.text.stream.LineIterator;

void main (char[][] args) {

   foreach (line; new LineIterator!(char)(Cin.input)) {
       // do something with each line
   }

}</lang>

Library: Tango

<lang d>import tango.io.Console; import tango.text.stream.SimpleIterator;

void main (char[][] args) {

   foreach (word; new SimpleIterator!(char)(" ", Cin.input)) {
       // do something with each word
   }

}</lang>

Note that foreach variables 'line' and 'word' are transient slices. If you need to retain them for later use, you should .dup them.

Delphi

<lang Delphi>program InputLoop;

{$APPTYPE CONSOLE}

uses SysUtils, Classes;

var

 lReader: TStreamReader; // Introduced in Delphi XE

begin

 lReader := TStreamReader.Create('input.txt', TEncoding.Default);
 try
   while lReader.Peek >= 0 do
     Writeln(lReader.ReadLine);
 finally
   lReader.Free;
 end;

end.</lang>

Déjà Vu

<lang dejavu>while /= :eof dup !read-line!stdin: !print( "Read a line: " !decode!utf-8 swap ) drop !print "End of file."</lang>

EasyLang

<lang>repeat

 l$ = input
 until error = 1
 print l$

.</lang>

Eiffel

Works with: Eiffel Studio version 6.6

<lang Eiffel> note description : "{ There are several examples included, including input from a text file, simple console input and input from standard input explicitly. See notes in the code for details.

Examples were compile using Eiffel Studio 6.6 with only the default class libraries. }"

class APPLICATION

create make

feature

make do -- These examples show non-console input (a plain text file) -- with end-of-input handling. read_lines_from_file read_words_from_file

-- These examples use simplified input from 'io', that -- handles the details of whether it's stdin or not -- They terminate on a line (word) of "q" read_lines_from_console_with_termination read_words_from_console_with_termination

-- The next examples show reading stdin explicitly -- as if it were a text file. It expects and end of file -- termination and so will loop indefinitely unless reading -- from a pipe or your console can send an EOF. read_lines_from_stdin read_words_from_stdin

-- These examples use simplified input from 'io', that -- handles the details of whether it's stdin or not, -- but have no explicit termination read_lines_from_console_forever read_words_from_console_forever end

--|--------------------------------------------------------------

read_lines_from_file -- Read input from a text file -- Echo each line of the file to standard output. -- -- Some language examples omit file open/close operations -- but are included here for completeness. Additional error -- checking would be appropriate in production code. local tf: PLAIN_TEXT_FILE do print ("Reading lines from a file%N") create tf.make ("myfile") -- Create a file object tf.open_read -- Open the file in read mode

-- The actual input loop

from until tf.end_of_file loop tf.read_line print (tf.last_string + "%N") end

tf.close -- Close the file end

--|--------------------------------------------------------------

read_words_from_file -- Read input from a text file -- Echo each word of the file to standard output on a -- separate line. -- -- Some language examples omit file open/close operations -- but are included here for completeness. Additional error -- checking would be appropriate in production code. local tf: PLAIN_TEXT_FILE do print ("Reading words from a file%N") create tf.make ("myfile") -- Create a file object tf.open_read -- Open the file in read mode

-- The actual input loop

from until tf.end_of_file loop -- This instruction is the only difference between this -- example and the read_lines_from_file example tf.read_word print (tf.last_string + "%N") end

tf.close -- Close the file end

--|--------------------------------------------------------------

read_lines_from_console_with_termination -- Read lines from console and echo them back to output -- until the line contains only the termination key 'q' -- -- 'io' is acquired through inheritance from class ANY, -- the top of all inheritance hierarchies. local the_cows_come_home: BOOLEAN do print ("Reading lines from console%N") from until the_cows_come_home loop io.read_line if io.last_string ~ "q" then the_cows_come_home := True print ("Mooooo!%N") else print (io.last_string) io.new_line end end end

--|--------------------------------------------------------------

read_words_from_console_with_termination -- Read words from console and echo them back to output, one -- word per line, until the line contains only the -- termination key 'q' -- -- 'io' is acquired through inheritance from class ANY, -- the top of all inheritance hierarchies. local the_cows_come_home: BOOLEAN do print ("Reading words from console%N") from until the_cows_come_home loop io.read_word if io.last_string ~ "q" then the_cows_come_home := True print ("Mooooo!%N") else print (io.last_string) io.new_line end end end

--|--------------------------------------------------------------

read_lines_from_console_forever -- Read lines from console and echo them back to output -- until the program is terminated externally -- -- 'io' is acquired through inheritance from class ANY, -- the top of all inheritance hierarchies. do print ("Reading lines from console (no termination)%N") from until False loop io.read_line print (io.last_string + "%N") end end

--|--------------------------------------------------------------

read_words_from_console_forever -- Read words from console and echo them back to output, one -- word per line until the program is terminated externally -- -- 'io' is acquired through inheritance from class ANY, -- the top of all inheritance hierarchies. do print ("Reading words from console (no termination)%N") from until False loop io.read_word print (io.last_string + "%N") end end

--|--------------------------------------------------------------

read_lines_from_stdin -- Read input from a stream on standard input -- Echo each line of the file to standard output. -- Note that we treat standard input as if it were a plain -- text file local tf: PLAIN_TEXT_FILE do print ("Reading lines from stdin (EOF termination)%N") tf := io.input

from until tf.end_of_file loop tf.read_line print (tf.last_string + "%N") end end

--|--------------------------------------------------------------

read_words_from_stdin -- Read input from a stream on standard input -- Echo each word of the file to standard output on a new -- line -- Note that we treat standard input as if it were a plain -- text file local tf: PLAIN_TEXT_FILE do print ("Reading words from stdin (EOF termination)%N") tf := io.input

from until tf.end_of_file loop tf.read_line print (tf.last_string + "%N") end end

end </lang>

Elena

ELENA 4.x:

Using ReaderEnumerator <lang elena>import system'routines; import system'io; import extensions'routines;

public program() {

   ReaderEnumerator.new(File.assign:"file.txt").forEach(printingLn)

}</lang> Using loop statement <lang elena>import system'io;

public program() {

   using(var reader := File.assign:"file.txt".textreader())
   {
       while (reader.Available)
       {
          console.writeLine(reader.readLine())
       }
   }

}</lang>

Elixir

<lang elixir>defmodule RC do

 def input_loop(stream) do
   case IO.read(stream, :line) do
     :eof -> :ok
     data -> IO.write data
             input_loop(stream)
   end
 end

end

path = hd(System.argv) File.open!(path, [:read], fn stream -> RC.input_loop(stream) end)</lang>

Erlang

<lang erlang>% Implemented by Arjun Sunel -module(read_files). -export([main/0]).

main() -> Read = fun (Filename) -> {ok, Data} = file:read_file(Filename), Data end, Lines = string:tokens(binary_to_list(Read("read_files.erl")), "\n"), lists:foreach(fun (Y) -> io:format("~s~n", [Y]) end, lists:zipwith(fun(X,_)->X end, Lines, lists:seq(1, length(Lines)))). </lang>

ERRE

input from stdio

     LOOP
       INPUT(LINE,A$)
       PRINT(A$)
       EXIT IF <condition> ! condition to be implemented to
                           ! to avoid and endless loop
     END LOOP

reading a text file line by line

     OPEN("I",#1,FILENAME$)
     WHILE NOT EOF(1)
         INPUT(LINE,#1,A$)
         PRINT(A$)
     END WHILE 
     CLOSE(1)

Note: with GET(#1) you can read character by character.

Euphoria

Process text stream line-by-line: <lang Euphoria>procedure process_line_by_line(integer fn)

   object line
   while 1 do
       line = gets(fn)
       if atom(line) then
           exit
       end if
       -- process the line
   end while

end procedure</lang>

F#

Using a sequence expression: <lang fsharp> let lines_of_file file =

 seq { use stream = System.IO.File.OpenRead file
       use reader = new System.IO.StreamReader(stream)
       while not reader.EndOfStream do
         yield reader.ReadLine() }

</lang> The file is reopened every time the sequence is traversed and lines are read on-demand so this can handle arbitrarily-large files.

Factor

<lang factor>"file.txt" utf8 [ [ process-line ] each-line ] with-file-reader</lang>

Fantom

An input stream can be from a string or from a file. The method eachLine will divide the stream by linebreaks. The method readStrToken takes two arguments: a maximum size to read, and a function to decide when to stop reading - by default, it stops when it finds a white space.

<lang fantom> class Main {

 public static Void main ()
 {
   // example of reading by line
   str := "first\nsecond\nthird\nword"
   inputStream := str.in
   inputStream.eachLine |Str line|
   {
     echo ("Line is: $line")
   }
   // example of reading by word
   str = "first second third word"
   inputStream = str.in
   word := inputStream.readStrToken // reads up to but excluding next space
   while (word != null)
   {
     echo ("Word: $word")
     inputStream.readChar // skip over the preceding space!
     word = inputStream.readStrToken
   }
 }

} </lang>

Forth

Works with: GNU Forth

<lang forth>4096 constant max-line

read-lines
 begin  stdin pad max-line read-line throw
 while  pad swap   \ addr len is the line of data, excluding newline
        2drop
 repeat ;</lang>

Fortran

Works with: Fortran version 90 and later

The code read line-by-line, but the maximum length of the line is limited (by a parameter)

<lang fortran>program BasicInputLoop

 implicit none
 integer, parameter        :: in = 50, &
                              linelen = 1000
 integer                   :: ecode
 character(len=linelen)    :: l
 open(in, file="afile.txt", action="read", status="old", iostat=ecode)
 if ( ecode == 0 ) then
    do
       read(in, fmt="(A)", iostat=ecode) l
       if ( ecode /= 0 ) exit
       write(*,*) trim(l)
    end do
    close(in)
 end if

end program BasicInputLoop</lang>

FreeBASIC

<lang freebasic>' FB 1.05.0 Win64

Dim line_ As String ' line is a keyword Open "input.txt" For Input As #1

While Not Eof(1)

 Input #1, line_
 Print line_  ' echo to the console

Wend

Close #1 Print Print "Press any key to quit" Sleep</lang>

Frink

<lang frink>while (line = readStdin[]) != undef

  println[line]

</lang>

FutureBasic

Note: This code goes beyond simply specifying the file to open. It includes a dialog window that allows the user to select a text file to read. The entire contents of the file are read in at once, rather than line by line. <lang futurebasic> include "ConsoleWindow"

local fn ReadTextFile dim as CFURLRef fileRef dim as Handle h dim as CFStringRef cfStr : cfStr = NULL dim as long fileLen

if ( files$( _CFURLRefOpen, "TEXT", "Select text file...", @fileRef ) )

  open "i", 2, fileRef
  fileLen = lof( 2, 1 )
  h = fn NewHandleClear( fileLen )
     if ( h )
        read file 2, [h], fileLen
        close #2
        cfStr = fn CFStringCreateWithBytes( _kCFAllocatorDefault, #[h], fn GetHandleSize(h), _kCFStringEncodingMacRoman, _false )
        fn DisposeH( h )
     end if

else // User canceled end if

fn HIViewSetText( sConsoleHITextView, cfStr ) CFRelease( cfStr ) end fn

fn ReadTextFile </lang>

gnuplot

The following gnuplot script echoes standard input to standard output line-by-line until the end of the stream. <lang gnuplot>!cat</lang> It makes use of the ability of gnuplot to spawn shell commands. In that sense it might be considered cheating. Nevertheless, this is a valid gnuplot script that does meet the requirements of the task description.

It seems impossible to complete this task with just standard gnuplot commands.

Go

The following reads a line at a time from stdin. <lang go>package main

import ( "bufio" "io" "log" "os" )

func main() { in := bufio.NewReader(os.Stdin) for { s, err := in.ReadString('\n') if err != nil { // io.EOF is expected, anything else // should be handled/reported if err != io.EOF { log.Fatal(err) } break } // Do something with the line of text // in string variable s. _ = s } }</lang> Or, using bufio.Scanner you can read line at a time, word at a time, byte or Unicode code point at a time, or by any custom "split function". <lang go>package main

import ( "bufio" "log" "os" )

func main() { s := bufio.NewScanner(os.Stdin) // Select the split function, other ones are available // in bufio or you can provide your own. s.Split(bufio.ScanWords) for s.Scan() { // Get and use the next 'token' asBytes := s.Bytes() // Bytes does no alloaction asString := s.Text() // Text returns a newly allocated string _, _ = asBytes, asString } if err := s.Err(); err != nil { // Handle/report any error (EOF will not be reported) log.Fatal(err) } }</lang>

Groovy

Solution: <lang groovy>def lineMap = [:] System.in.eachLine { line, i ->

   lineMap[i] = line

} lineMap.each { println it }</lang>

Test:
$ groovy -e 'def lineMap = [:]
> System.in.eachLine { line, i ->
>     lineMap[i] = line
> }
> lineMap.each { println it }' <<EOF
> 
> Whose woods these are I think I know
> His house is in the village tho'
> He will not see me stopping here
> To watch his woods fill up with snow
> EOF
Output:
1=
2=Whose woods these are I think I know
3=His house is in the village tho'
4=He will not see me stopping here
5=To watch his woods fill up with snow

Haskell

The whole contents of a file can be read lazily. The standard functions lines and words convert that lazily into the lists of lines resp. words. Usually, one wouldn't use extra routines for that, but just use readFile and then put 'lines' or words somewhere in the next processing step.

<lang haskell>import System.IO

readLines :: Handle -> IO [String] readLines h = do

 s <- hGetContents h
 return $ lines s

readWords :: Handle -> IO [String] readWords h = do

 s <- hGetContents h
 return $ words s</lang>

HicEst

<lang HicEst>CHARACTER name='myfile.txt', string*1000

  OPEN(FIle=name, OLD, LENgth=bytes, IOStat=errorcode, ERror=9)
  DO line = 1, bytes  ! loop terminates with end-of-file error at the latest
     READ(FIle=name, IOStat=errorcode, ERror=9) string
     WRITE(StatusBar) string
  ENDDO
9 WRITE(Messagebox, Name) line, errorcode</lang>

i

<lang i>software { loop { read() errors { exit } } }</lang>

Icon and Unicon

<lang Icon>link str2toks

  1. call either words or lines depending on what you want to do.

procedure main()

  words()

end

procedure lines()

  while write(read())

end

procedure words()

  local line
  while line := read() do line ? every write(str2toks())

end</lang>

See str2toks

J

Script "read-input-until-eof.ijs": <lang J>#!/Applications/j602/bin/jconsole NB. read input until EOF ((1!:1) 3)(1!:2) 4 exit </lang> Example: <lang J>$ ./read-input-to-eof.ijs <<EOF > abc > def > ghi > now is the time for all good men ... > EOF abc def ghi now is the time for all good men ...</lang>

Java

Some people prefer Scanner or BufferedReader, so a way with each is presented. <lang java>import java.io.InputStream; import java.util.Scanner;

public class InputLoop {

   public static void main(String args[]) {
       // To read from stdin:
       InputStream source = System.in;
       /*
       Or, to read from a file:
       InputStream source = new FileInputStream(filename);
       Or, to read from a network stream:
       InputStream source = socket.getInputStream();
       */
       Scanner in = new Scanner(source);
       while(in.hasNext()){
           String input = in.next(); // Use in.nextLine() for line-by-line reading
           // Process the input here. For example, you could print it out:
           System.out.println(input);
       }
   }

}</lang> Or <lang java>import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader;

public class InputLoop {

   public static void main(String args[]) {
       // To read from stdin:
       Reader reader = new InputStreamReader(System.in);
       /*
       Or, to read from a file:
       Reader reader = new FileReader(filename);
       Or, to read from a network stream:
       Reader reader = new InputStreamReader(socket.getInputStream());
       */
       try {
           BufferedReader inp = new BufferedReader(reader);
           while(inp.ready()) {
               int input = inp.read(); // Use in.readLine() for line-by-line
               // Process the input here. For example, you can print it out.
               System.out.println(input);
           }
       }  catch (IOException e) {
           // There was an input error.
       }
   }

}</lang>

JavaScript

Works with: SpiderMonkey
Works with: OSSP js

These implementations of JavaScript define a readline() function, so:

$ js -e 'while (line = readline()) { do_something_with(line); }' < inputfile
Works with: JScript

As above, this operates on standard input <lang javascript>var text_stream = WScript.StdIn; var i = 0;

while ( ! text_stream.AtEndOfStream ) {

   var line = text_stream.ReadLine();
   // do something with line
   WScript.echo(++i + ": " + line);

}</lang>

jq

The jq program for reading and writing is simply the one-character program:

   .

For example, to echo each line of text in a file, one could invoke jq as follows:<lang jq>jq -r -R . FILENAME </lang>

If the input file consists of well-formed JSON entities (including scalars), then the following invocation could be used to "pretty-print" the input: <lang jq>jq . FILENAME</lang>

Other options, e.g. to emit JSON in compact form, also exist.

Jsish

<lang javascript>/* Input loop in Jsish */

var line; var cs = 0, ls = 0;

while (line = console.input()) { cs += line.length; ls += 1; }

printf("%d lines, %d characters\n", ls, cs);</lang>

Output:
prompt$ jsish input-loop.jsi <input-loop.jsi
8 lines, 159 characters

Julia

We create a text stream and read the lines from the stream one by one, printing them on screen. Note that the lines end by a newline, except the last one. The ending newlines are part of the strings returned by the function readline. Once the end of the stream is reached, readline returns an empty string. <lang julia>stream = IOBuffer("1\n2\n3\n4\n\n6")

while !eof(stream)

   line = readline(stream)
   println(line)

end</lang>

Output:
1
2
3
4

6

Kotlin

<lang scala>// version 1.1

import java.util.*

fun main(args: Array<String>) {

   println("Keep entering text or the word 'quit' to end the program:")
   val sc = Scanner(System.`in`)
   val words = mutableListOf<String>()
   while (true) {
       val input: String = sc.next()
       if (input.trim().toLowerCase() == "quit") {
           if (words.size > 0) println("\nYou entered the following words:\n${words.joinToString("\n")}")
           return
       }
       words.add(input)
   }

}</lang> Sample input/output:

Output:
Keep entering text or the word 'quit' to end the program:
The quick brown fox
jumps over the lazy dog
quit

You entered the following words:
The
quick
brown
fox
jumps
over
the
lazy
dog

Lang5

<lang lang5>: read-lines do read . "\n" . eof if break then loop ;

==>contents
   '< swap open 'fh set fh fin read-lines fh close ;

'file.txt ==>contents</lang>

Lasso

<lang Lasso> local( myfile = file('//path/to/file.txt'), textresult = array )

  1. myfile -> foreachline => {

#textresult -> insert(#1) }

  1. textresult -> join('
    ')</lang>

Result: This is line one I am the second line Here is line 3

Liberty BASIC

<lang lb> filedialog "Open","*.txt",file$ if file$="" then end open file$ for input as #f while not(eof(#f))

   line input #f, t$
   print t$

wend close #f end </lang>

LIL

From the canread.lil sample that ships with LIL.

<lang tcl>#

  1. canread test (note that canread is not available in LIL/FPLIL itself
  2. but provided by the command line interfaces in main.c/lil.pas)
  3. You can either call this and enter lines directly (use Ctrl+Z/Ctrl+D
  4. to finish) or a redirect (e.g. lil canread.lil < somefile.txt)
  5. Normally this is how you are supposed to read multiple lines from
  6. the standard input using the lil executable. For an alternative way
  7. that uses error catching via try see the eoferror.lil script.

set count 0 while {[canread]} {

   readline
   inc count

} print $count lines</lang>

Output:
prompt$ lil canread.lil <canread.lil
19 lines

There are several words which will return a line of input.

  • readline - returns a line as a list of words
  • readword - returns a line as a single word, or an empty list if it reached the end of file
  • readrawline - returns a line as a single word, with no characters escaped

<lang logo>while [not eof?] [print readline]</lang>

LSL

LSL doesn't have a File System, but it does have Notecards that function as read-only text files, and can be use as configuration files or data sources.

To test it yourself; rez a box on the ground, add the following as a New Script, create a notecard named "Input_Loop_Data_Source.txt", and put what ever data you want in it (in this case I just put a copy of the source code.) <lang LSL>string sNOTECARD = "Input_Loop_Data_Source.txt"; default { integer iNotecardLine = 0; state_entry() { llOwnerSay("Reading '"+sNOTECARD+"'"); llGetNotecardLine(sNOTECARD, iNotecardLine); } dataserver(key kRequestId, string sData) { if(sData==EOF) { llOwnerSay("EOF"); } else { llOwnerSay((string)iNotecardLine+": "+sData); llGetNotecardLine(sNOTECARD, ++iNotecardLine); } } }</lang>

Output:
Reading 'Input_Loop_Data_Source.txt'
0: string sNOTECARD = "Input_Loop_Data_Source.txt";
1: default {
2: 	integer iNotecardLine = 0;
3: 	state_entry() {
4: 		llOwnerSay("Reading '"+sNOTECARD+"'"); 
5: 		llGetNotecardLine(sNOTECARD, iNotecardLine);
6: 	}
7: 	dataserver(key kRequestId, string sData) {
8: 		if(sData==EOF) {
9: 			llOwnerSay("EOF");
10: 		} else {
11: 			llOwnerSay((string)iNotecardLine+": "+sData);
12: 			llGetNotecardLine(sNOTECARD, ++iNotecardLine);
13: 		}
14: 	}
15: }
EOF

Lua

<lang lua>lines = {} str = io.read() while str do

   table.insert(lines,str)
   str = io.read()

end</lang>

Via generic for loop

Reads line-by-line via an iterator (from stdin). Substitute io.lines() with io.open(filename, "r"):lines() to read from a file.

<lang lua>lines = {}

for line in io.lines() do

   table.insert(lines, line) -- add the line to the list of lines

end</lang>

M2000 Interpreter

<lang M2000 Interpreter> Document A$={1st Line

     2nd line
     3rd line
     }

Save.Doc A$, "test.txt", 0 ' 0 for utf16-le \\ we use Wide for utf16-le \\ without it we open using ANSI Open "test.txt" For Wide Input Exclusive as #N

     While Not Eof(#N) {
           Line Input #N, ThisLine$
           Print ThisLine$
     }

Close #N Clear A$ Load.Doc A$, "test.txt" \\ print proportional text, all lines Report A$ \\ Print one line, non proportional \\ using paragraphs For i=0 to Doc.par(A$)-1

     Print Paragraph$(A$, i)

Next i \\ List of current variables (in any scope, public only) List </lang>

Maple

<lang Maple> readinput:=proc(filename) local line,file; file:=""; line:=readline(filename); while line<>0 do line:=readline(filename); file:=cat(file,line); end do; end proc; </lang>

Mathematica / Wolfram Language

<lang Mathematica>stream = OpenRead["file.txt"]; While[a != EndOfFile, Read[stream, Word]]; Close[stream]</lang>

MAXScript

this function will read a file line by line. <lang MAXScript>fn ReadAFile FileName = ( local in_file = openfile FileName while not eof in_file do ( --Do stuff in here-- print (readline in_file) ) close in_file )</lang>

Mercury

<lang>

- module input_loop.
- interface.
- import_module io.
- pred main(io::di, io::uo) is det.
- implementation.

main(!IO) :-

   io.stdin_stream(Stdin, !IO),
   io.stdout_stream(Stdout, !IO),
   read_and_print_lines(Stdin, Stdout, !IO).
- pred read_and_print_lines(io.text_input_stream::in,
   io.text_output_stream::in, io::di, io::uo) is det.

read_and_print_lines(InFile, OutFile, !IO) :-

   io.read_line_as_string(InFile, Result, !IO),
   (
       Result = ok(Line),
       io.write_string(OutFile, Line, !IO),
       read_and_print_lines(InFile, OutFile, !IO)
   ;
       Result = eof
   ;
       Result = error(IOError),
       Msg = io.error_message(IOError),
       io.stderr_stream(Stderr, !IO),
       io.write_string(Stderr, Msg, !IO),
       io.set_exit_status(1, !IO)
   ).

</lang>

mIRC Scripting Language

<lang mirc>var %n = 1 while (%n <= $lines(input.txt)) {

 write output.txt $read(input.txt,%n)
 inc %n

}</lang>

ML/I

The very nature of ML/I is that its default behaviour is to copy from input to output until it reaches end of file. <lang ML/I></lang>

Modula-2

<lang modula2>PROCEDURE ReadName (VAR str : ARRAY OF CHAR);

VAR n  : CARDINAL;

       ch, endch       : CHAR;

BEGIN

  REPEAT
     InOut.Read (ch);
     Exhausted := InOut.EOF ();
     IF  Exhausted  THEN  RETURN  END
  UNTIL  ch > ' ';             (* Eliminate whitespace         *)
  IF  ch = '['  THEN  endch := ']'  ELSE  endch := ch  END;
  n := 0;
  REPEAT
     InOut.Read (ch);
     Exhausted := InOut.EOF ();
     IF  Exhausted  THEN  RETURN  END;
     IF  n <= HIGH (str)  THEN  str [n] := ch  ELSE  ch := endch  END;
     INC (n)
  UNTIL ch = endch;
  IF  n <= HIGH (str)  THEN  str [n-1] := 0C  END;
  lastCh := ch

END ReadName;</lang>

Modula-3

<lang modula3>MODULE Output EXPORTS Main;

IMPORT Rd, Wr, Stdio;

VAR buf: TEXT;

<*FATAL ANY*>

BEGIN

 WHILE NOT Rd.EOF(Stdio.stdin) DO
   buf := Rd.GetLine(Stdio.stdin);
   Wr.PutText(Stdio.stdout, buf);
 END;

END Output.</lang>

NetRexx

Using NetRexx ASK Special Variable

<lang NetRexx>/* NetRexx */ options replace format comments java crossref symbols nobinary

-- Read from default input stream (console) until end of data lines = lines[0] = 0 lineNo = 0

loop label ioloop forever

 inLine = ask
 if inLine =  null  then leave ioloop -- stop on EOF (Try Ctrl-D on UNIX-like systems or Ctrl-Z on Windows)
 lineNo = lineNo + 1
 lines[0] = lineNo
 lines[lineNo] = inLine
 end ioloop

loop l_ = 1 to lines[0]

 say l_.right(4)':' lines[l_]
 end l_

return </lang>

Using Java Scanner

<lang NetRexx>/* NetRexx */ options replace format comments java crossref symbols nobinary

-- Read from default input stream (console) until end of data lines = lines[0] = 0

inScanner = Scanner(System.in) loop l_ = 1 while inScanner.hasNext()

 inLine = inScanner.nextLine()
 lines[0] = l_
 lines[l_] = inLine
 end l_

inScanner.close()

loop l_ = 1 to lines[0]

 say l_.right(4)':' lines[l_]
 end l_

return </lang>

Nim

<lang nim>var i = open("input.txt") for line in i.lines:

 discard # process line

i.close()</lang>

Oberon-2

Works with oo2c Version 2 <lang oberon2> MODULE InputLoop; IMPORT

 StdChannels,
 Channel;

VAR

 reader: Channel.Reader;
 writer: Channel.Writer;
 c: CHAR;

BEGIN

 reader := StdChannels.stdin.NewReader();
 writer := StdChannels.stdout.NewWriter();
 
 reader.ReadByte(c);
 WHILE reader.res = Channel.done DO
   writer.WriteByte(c);
   reader.ReadByte(c)
 END

END InputLoop. </lang> Execute: InputLoop < Inputloop.Mod
Output:

MODULE InputLoop;
IMPORT
  StdChannels,
  Channel;
VAR
  reader: Channel.Reader;
  writer: Channel.Writer;
  c: CHAR;
BEGIN
  reader := StdChannels.stdin.NewReader();
  writer := StdChannels.stdout.NewWriter();
  
  reader.ReadByte(c);
  WHILE reader.res = Channel.done DO
    writer.WriteByte(c);
    reader.ReadByte(c)
  END
END InputLoop.

Objeck

<lang objeck> use IO;

bundle Default {

 class Test {
   function : Main(args : System.String[]) ~ Nil {
     f := FileReader->New("in.txt");
     if(f->IsOpen()) {
       string := f->ReadString();
       while(string->Size() > 0) {
         string->PrintLine();
         string := f->ReadString();
       };
       f->Close();
     };
   }
 }

} </lang>

OCaml

<lang ocaml>let rec read_lines ic =

 try let line = input_line ic in
   line :: read_lines ic
 with End_of_file ->
   []</lang>

The version above will work for small files, but it is not tail-recursive.
Below will be more scalable:

<lang ocaml>let read_line ic =

 try Some (input_line ic)
 with End_of_file -> None

let read_lines ic =

 let rec loop acc =
   match read_line ic with
   | Some line -> loop (line :: acc)
   | None -> List.rev acc
 in
 loop []
</lang>

Or with a higher order function:

<lang ocaml>let read_lines f ic =

 let rec loop () =
   try f(input_line ic); loop()
   with End_of_file -> ()
 in
 loop()

read_lines print_endline (open_in Sys.argv.(1))</lang>

This function will apply your_function() to every line of input <lang ocaml> let rec input_caller () =

 let input = read_line() in
 your_function input ;
 input_caller() ;

let () = input_caller()</lang>

Oforth

Reads a file line by line and write each line on standard output :

<lang Oforth>: readFile(filename) File new(filename) apply(#println) ; </lang>

Oz

<lang oz>%% Returns a list of lines. %% Text: an instance of Open.text (a mixin class) fun {ReadAll Text}

  case {Text getS($)} of false then nil
  [] Line then Line|{ReadAll Text}
  end

end</lang>

Pascal

<lang pascal>{ for stdio }

var

s : string ;

begin

 repeat
   readln(s);

 until s = "" ;

{ for a file }

var

f : text ;
s : string ;

begin

 assignfile(f,'foo');
 reset(f);
 
 while not eof(f) do
   readln(f,s);
 closefile(f);

end;</lang>

Perl

The angle brackets operator ( <...> ) reads one line at a time from a filehandle in scalar context: <lang perl>open FH, "< $filename" or die "can't open file: $!"; while (my $line = <FH>) {

   chomp $line; # removes trailing newline
   # process $line

} close FH or die "can't close file: $!";</lang>

Or you can get a list of all lines when you use it in list context: <lang perl>@lines = <FH>;</lang>

Or a simpler program for lines of files entered as command line arguments or standard input: <lang perl>while (<>) {

   # $_ contains a line

}</lang>

Invoking perl with the -p or -n option implies the above loop, executing its code once per input line, with the line stored in $_. -p will print $_ automatically at the end of each iteration, -n will not.

$ seq 5 | perl -pe '$_ = "Hello $_"'
Hello 1
Hello 2
Hello 3
Hello 4
Hello 5
$ seq 5 | perl -ne 'print "Hello $_"'
Hello 1
Hello 2
Hello 3
Hello 4
Hello 5

Phix

Translation of: Euphoria

Process text stream line-by-line: <lang Phix>procedure process_line_by_line(integer fn)

   object line
   while 1 do
       line = gets(fn)
       if atom(line) then
           exit
       end if
       -- process the line
   end while

end procedure</lang>

PHP

<lang php>$fh = fopen($filename, 'r'); if ($fh) {

   while (!feof($fh)) {
       $line = rtrim(fgets($fh)); # removes trailing newline
       # process $line
   }
   fclose($fh);

}</lang>

Or you can get an array of all the lines in the file: <lang php>$lines = file($filename);</lang>

Or you can get the entire file as a string: <lang php>$contents = file_get_contents($filename);</lang>

PicoLisp

This reads all lines in a file, and returns them as a list of lists <lang PicoLisp>(in "file.txt"

  (make
     (until (eof)
        (link (line)) ) ) )</lang>

PL/I

<lang pli>declare line character (200) varying;

open file (in) title ('/TEXT.DAT,type(text),recsize(200)' ); on endfile (in) stop;

do forever;

  get file(in) edit (line) (L);
  put skip list (line);

end;</lang>

PowerShell

<lang Powershell>Get-Content c:\file.txt |

   ForEach-Object {
       $_
   }</lang>

or <lang Powershell>ForEach-Object -inputobject (get-content c:\file.txt) {$_}</lang>

PureBasic

File objects can be read bytewise, characterwise (ASCII or UNICODE), floatwise, doublewise, integerwise, linewise ... <lang PureBasic>If OpenConsole()

 ; file based line wise
 If ReadFile(0, "Text.txt")  
   While Eof(0) = 0          
     Debug ReadString(0)      ; each line until eof
   Wend
   CloseFile(0)               
 EndIf
 
 ; file based byte wise
 If ReadFile(1, "Text.bin")  
   While Eof(1) = 0          
     Debug ReadByte(1)      ; each byte until eof
   Wend
   CloseFile(1)               
 EndIf

EndIf</lang>

Python

To create a Python3 input loop use python's `input()` function.

<lang python>while(True):

     x = input("What is your age? ")
     print(x)</lang>

Python file objects can be iterated like lists:

<lang python>my_file = open(filename, 'r') try:

   for line in my_file:
       pass # process line, includes newline

finally:

   my_file.close()</lang>

One can open a new stream for read and have it automatically close when done, with a new "with" statement: <lang python>from __future__ import with_statement

with open(filename, 'r') as f:

   for line in f:
       pass # process line, includes newline</lang>

You can also get lines manually from a file: <lang python>line = my_file.readline() # returns a line from the file lines = my_file.readlines() # returns a list of the rest of the lines from the file</lang> This does not mix well with the iteration, however.


When you want to read from stdin, or (multiple) filenames are given on the command line: <lang python>import fileinput for line in fileinput.input():

   pass # process line, includes newline</lang>

The fileinput module can also do inplace file editing, follow line counts, and the name of the current file being read etc.

R

Note that read.csv and read.table provide alternatives for files with 'dataset' style contents. <lang rsplus>lines <- readLines("file.txt")</lang>

Racket

The following prints input lines from standard input to standard output: <lang racket>

  1. lang racket

(copy-port (current-input-port) (current-output-port)) </lang>

Raku

(formerly Perl 6)

In Raku, filehandles etc. provide the .lines and .words methods which return lazy lists, and can thus they be iterated using a for loop...

Line-by-line (line endings are automatically stripped)

  • From a file:<lang perl6>for "filename.txt".IO.lines -> $line {
   ...

}</lang>

  • From standard input:<lang perl6>for $*IN.lines -> $line {
   ...

}</lang>

  • From a pipe:<lang perl6>for run(«find -iname *.txt», :out).out.lines -> $filename {
   ...

}</lang>

  • From a pipe, with custom line separator (in this example to handle filenames containing newlines):<lang perl6>for run(«find -iname *.txt -print0», :nl«\0», :out).out.lines -> $filename {
   ...

}</lang>

Word-by-word

  • From a file <lang perl6>for "filename.txt".IO.words -> $word {
   ...

}</lang>

  • From standard input or a pipe, accordingly.

REBOL

<lang REBOL>REBOL [ Title: "Basic Input Loop" URL: http://rosettacode.org/wiki/Basic_input_loop ]

Slurp the whole file in

x: read %file.txt

Bring the file in by lines

x: read/lines %file.txt

Read in first 10 lines

x: read/lines/part %file.txt 10

Read data a line at a time

f: open/lines %file.txt while [not tail? f][ print f/1 f: next f ; Advance to next line. ] close f</lang>

REXX

version 1a

Works with: oorexx and Regina

Reading line by line from the standard input using linein and lines did not work. <lang rexx>do while stream(stdin, "State") <> "NOTREADY"

 call charout ,charin(stdin)

end</lang>

version 1b

Works with: oorexx and Regina

Apparently only lines() does not work <lang rexx>Do Until input=

 input=linein(stdin)
 Call lineout ,input
 End</lang>

version 2

Works with: ARexx

<lang rexx>/* -- AREXX -- */ do until eof(stdin)

 l = readln(stdin)
 say l

end</lang>

version 3

Note that if REXX is reading from the default (console) input stream, there is no well-
defined e-o-f (end of file), so to speak.

Therefore, the following two REXX programs use the presence of a null line to indicate e-o-f. <lang rexx>/*REXX program reads from the (console) default input stream until null*/

      do  until _==
      parse pull _                    
      end   /*until*/                 /*stick a fork in it, we're done.*/</lang>

version 4

<lang rexx>/*REXX program reads from the (console) default input stream until null*/

      do  until _==
      _= linein()
      end   /*until*/                 /*stick a fork in it, we're done.*/</lang>

Ring

<lang ring> fp = fopen("C:\Ring\ReadMe.txt","r")

r = fgetc(fp) while isstring(r)

     r = fgetc(fp)
     if r = char(10) see nl
     else see r ok

end fclose(fp)

</lang>

Ruby

Ruby input streams are IO objects. One can use IO#each or IO#each_line to iterate lines from a stream.

<lang ruby>stream = $stdin stream.each do |line|

 # process line

end</lang>

IO objects are also Enumerable (like Array or Range), and have methods like Enumerable#map, which call IO#each to loop through lines from a stream.

<lang ruby># Create an array of lengths of every line. ary = stream.map {|line| line.chomp.length}</lang>

To open a new stream for reading, see Read a file line by line#Ruby.

Run BASIC

<lang runbasic>open "\testFile.txt" for input as #f while not(eof(#f)) line input #f, a$ print a$ wend close #f</lang>

Rust

<lang Rust> use std::io::{self, BufReader, Read, BufRead}; use std::fs::File;

fn main() {

   print_by_line(io::stdin())
       .expect("Could not read from stdin");
   File::open("/etc/fstab")
       .and_then(print_by_line)
       .expect("Could not read from file");

}

fn print_by_line<T: Read>(reader: T) -> io::Result<()> {

   let buffer = BufReader::new(reader);
   for line in buffer.lines() {
       println!("{}", line?)
   }
   Ok(())

}</lang>

Scala

Library: Scala
Works with: Scala version 2.10.3

<lang scala> scala.io.Source.fromFile("input.txt").getLines().foreach {

   line => ... }</lang>

sed

Sed by default loops over each line and executes its given script on it:

$ seq 5 | sed ''
1
2
3
4
5

The automatic printing can be suppressed with -n, and performed manually with p:

$ seq 5 | sed -n p
1
2
3
4
5

Seed7

<lang seed7>$ include "seed7_05.s7i";

const proc: main is func

 local
   var string: line is "";
 begin
   while hasNext(IN) do
     readln(line);
     writeln("LINE: " <& line);
   end while;
 end func;</lang>

Sidef

To read from the standard input, you can use STDIN as your fh. <lang ruby>var file = File(__FILE__) file.open_r(\var fh, \var err) || die "#{file}: #{err}"

fh.each { |line| # iterates the lines of the fh

   line.each_word { |word|   # iterates the words of the line
       say word
   }

}</lang>

Slate

<lang slate>(File newNamed: 'README') reader sessionDo: [| :input | input lines do: [| :line | inform: line]].</lang>

Smalltalk

<lang smalltalk>|f| f := FileStream open: 'afile.txt' mode: FileStream read. [ f atEnd ] whileFalse: [ (f nextLine) displayNl ] .</lang>

SNOBOL4

<lang snobol>loop output = input :s(loop) end</lang>

Sparkling

<lang sparkling>var line; while (line = getline()) != nil {

   print(line);

}</lang>

Tcl

<lang tcl>set fh [open $filename] while {[gets $fh line] != -1} {

   # process $line

} close $fh</lang> For “small” files, it is often more common to do this: <lang tcl>set fh [open $filename] set data [read $fh] close $fh foreach line [split $data \n] {

   # process line

}</lang>

TUSCRIPT

<lang tuscript> $$ MODE TUSCRIPT file="a.txt" ERROR/STOP OPEN (file,READ,-std-) ACCESS source: READ/RECORDS/UTF8 $file s,text LOOP

   READ/NEXT/EXIT source
   PRINT text

ENDLOOP ENDACCESS source </lang>

UNIX Shell

When there is something to do with the input, here is a loop: <lang bash>while read line ; do

 # examine or do something to the text in the "line" variable
 echo "$line"

done</lang> The following echoes standard input to standard output line-by-line until the end of the stream. <lang bash>cat < /dev/stdin > /dev/stdout</lang> Since cat defaults to reading from standard input and writing to standard output, this can be further simplified to the following. <lang bash>cat</lang>

UnixPipes

the pipe 'yes XXX' produces a sequence

read by lines: <lang bash>yes 'A B C D ' | while read x ; do echo -$x- ; done</lang> read by words: <lang bash>yes 'A B C D ' | while read -d\ a ; do echo -$a- ; done</lang>

Ursa

<lang ursa>decl file f f.open "filename.txt" while (f.hasnext) out (in string f) endl console end while</lang>

Vala

<lang vala>int main() {

       string? s;
       while((s = stdin.read_line()) != null) {
               stdout.printf("%s\n", s);
       }
       return 0;

}</lang>

VBA

<lang vb>Public Sub test()

   Dim filesystem As Object, stream As Object, line As String
   Set filesystem = CreateObject("Scripting.FileSystemObject")
   Set stream = filesystem.OpenTextFile("D:\test.txt")
   Do While stream.AtEndOfStream <> True
       line = stream.ReadLine
       Debug.Print line
   Loop
   stream.Close

End Sub</lang>

VBScript

<lang vb> filepath = "SPECIFY PATH TO TEXT FILE HERE"

Set objFSO = CreateObject("Scripting.FileSystemObject") Set objInFile = objFSO.OpenTextFile(filepath,1,False,0)

Do Until objInFile.AtEndOfStream line = objInFile.ReadLine WScript.StdOut.WriteLine line Loop

objInFile.Close Set objFSO = Nothing </lang>

Visual Basic .NET

This reads a stream line by line, outputing each line to the screen.

<lang vbnet>Sub Consume(ByVal stream As IO.StreamReader)

   Dim line = stream.ReadLine
   Do Until line Is Nothing
       Console.WriteLine(line)
       line = stream.ReadLine
   Loop

End Sub</lang>

x86 Assembly

GAS, 64 bit (Linux): Compiled with gcc -nostdlib. Memory maps the file and outputs one line at a time. Try ./a.out file, ./a.out < file, or ./a.out <<< "Heredoc". It's a little like cat, but less functional. <lang x86>#define SYS_WRITE $1

  1. define SYS_OPEN $2
  2. define SYS_CLOSE $3
  3. define SYS_FSTAT $5
  4. define SYS_MMAP $9
  5. define SYS_MUNMAP $11
  6. define SYS_EXIT $60

// From experiments:

  1. define FSIZEOFF 48
  2. define STATSIZE 144

// From Linux source:

  1. define RDONLY $00
  2. define PROT_READ $0x1
  3. define MAP_PRIVATE $0x02
  4. define STDIN $0
  5. define STDOUT $1

.global _start .text

/* Details: */ /*

   Remember:  %rax(%rdi, %rsi, %rdx, %r10, %r8, %r9)
   - Open a file (get its fd)
       - int fd = open("filename", RDONLY)
   - Get its filesize:
       - fstat(fd, statstruct). 0 if ok. fsize at statstruct+48
   - Then memory map it.
       - void* vmemptr = mmap(vmemptr, fsize, PROT_READ, MAP_PRIVATE, fd, 0)
   - Scan for newlines, print line.
       - Keep going until done. Details at 11.
   - Unmap memory
       - munmap(vmemptr, filesize). 0 if ok.
   - Exit
*/
   

.macro ERRCHECK code

   cmpq    $\code, %rax
   je      fs_error

.endm

/* Local stack notes:

   0: int fd
   4: void* vmemptr
   12: void* head
   20: void* lookahead
   28: void* end
  • /

_start:

   // Open:
   movq    RDONLY, %rsi
   // Filename ptr is on stack currently as argv[1]:
   cmpq    $1, (%rsp)          // if argc is 1, default to stdin
   jnz     open_file
   subq    $36, %rsp           // local stack
   movl    STDIN, (%rsp)
   jmp     fstat
   
   open_file:
   movq    16(%rsp), %rdi      // argc(8), argv0(8) => rsp+16. filename
   movq    SYS_OPEN, %rax
   syscall
   ERRCHECK    -1
   subq    $36, %rsp           // local stack
   movl    %eax, (%rsp)        // int fd = open(argv[1], RDONLY)
   
   // fstat to get filesize
   fstat:
   movq    $statstruct, %rsi
   movl    (%rsp), %edi        // fd
   movq    SYS_FSTAT, %rax
   syscall                     // fstat(fd, statstruct)
   ERRCHECK    -1
   
   // mmap - don't forget to munmap.
   mmap:
   movq    $0, %r9             // offset
   movq    (%rsp), %r8         // fd
   movq    MAP_PRIVATE, %r10
   movq    PROT_READ, %rdx
   movq    filesize, %rsi
   movq    (%rsp), %rdi        // vmemptr
   movq    SYS_MMAP, %rax
   syscall
   ERRCHECK    -1
   movq    %rax, 4(%rsp)       // void* vmemptr = mmap(vmemptr, fsize, PROT_READ, MAP_PRIVATE, fd, 0)
   
   /* Print lines */ 
   movq    %rax, 12(%rsp)  // head = vmemptr
   addq    filesize, %rax
   decq    %rax
   movq    %rax, 28(%rsp)  // end = vmemptr+filesize-1
   scan_outer:
       movq    12(%rsp), %rax
       cmpq    28(%rsp), %rax
       jge     cleanup         // if head >= end, done
       movq    %rax, %rbx      // Using rbx as lookahead
       scan_inner:
           cmpq    28(%rsp), %rbx
           jge     writeline       // if lookahead >= end, write the line.
           cmpb    $'\n, (%rbx)
           jz      writeline       // if '\n'==*lookahead, write the line
           incq    %rbx
           jmp     scan_inner
       writeline:
           // write:
           incq    %rbx
           movq    %rbx, %rdx
           subq    12(%rsp), %rdx  // rdx <- lookahead-head
           movq    12(%rsp), %rsi
           movq    STDOUT, %rdi
           movq    SYS_WRITE, %rax
           syscall                 // write(stdout, head, lookahead-head)
           safety:
           movq    %rbx, 12(%rsp)  // head = lookahead.
           jmp     scan_outer
   
   cleanup:
   // munmap
   movq    filesize, %rsi
   movq    4(%rsp), %rdi
   movq    SYS_MUNMAP, %rax
   syscall                     // munmap(vmemptr, filesize)
   cmpq    $-1, %rax
   je      fs_error
   // close
   movl    (%rsp), %edi
   movq    SYS_CLOSE, %rax
   syscall                     // close(fd)
   ERRCHECK    -1

exit:

   movq    SYS_EXIT, %rax
   xorq    %rdi, %rdi              // The exit code.
   syscall
   

fs_error:

   movq    SYS_EXIT, %rax
   movq    $-1, %rdi
   syscall                         // exit(-1)

.data statstruct: // This struct is 144 bytes. Only want size (+48)

   .zero FSIZEOFF
   filesize:  // 8 bytes.
   .quad   0
   .zero   STATSIZE-FSIZEOFF+8</lang>

XPL0

Text stream is a file redirected on command line i.e: <file.txt <lang XPL0>int C; [repeat \read file

       repeat                          \read line
               repeat  C:= ChIn(1);    \read word
                       ChOut(0, C);
               until   (C<^A ! C>^z) & (C<^0 ! C>^9);  \non-alphanumeric
       until   C < $20;                \CR, LF, or EOF

until C = \EOF\ $1A; ]</lang>

zkl

Many objects support "stream of" concepts such as lines, characters, chunks. Some are File, Data (bit bucket), List, Console. Word by word isn't explicitly supported. If an object is stream-able, it supports methods like foreach, pump, apply, reduce, etc. <lang zkl>foreach line in (File("foo.txt")){...} List(1,2,3).readln() // here, a "line" is a list element Utils.Helpers.zipWith(False, // enumerate a file

  fcn(n,line){"%3d: %s".fmt(n,line).print()},[1..],File("cmp.zkl"))</lang>