Input loop

From Rosetta Code
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.

Read from a text stream either word-by-word or line-by-line until the stream runs out of data. The stream will have an unknown amount of data on it.

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>

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.

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>

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>

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>

C

<lang c>#include <stdio.h>

  1. define MAX_LEN 20

/* line by line: */ /* This may not read the whole line; just up to MAX_LEN characters at a time. */ void process_lines(FILE *stream) {

 char line[MAX_LEN + 1];
 while (fgets(line, MAX_LEN + 1, stream) != NULL) {
   /* process the string here */
   /* the string includes the line return, if it reached the end of line */
 }

}

/* word by word */ /* This may not read the whole word; just up to MAX_LEN characters at a time. */

  1. define Str(x) #x
  2. define Xstr(x) Str(x)

void process_words(FILE *stream) {

 char word[MAX_LEN + 1];
 while (fscanf(stream, "%" Xstr(MAX_LEN) "s", word) == 1) {
   /* process the string here */
 }

}</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>

C#

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

class Program {

   static void Main(string[] args)
   {
       StreamReader b = new StreamReader("file.txt"); //or any other Stream
       string line = b.ReadLine();
       while (line != null)
       {
           Console.WriteLine(line);
           line = b.ReadLine();
       }
   }

}</lang>

Clojure

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

 (line-seq (java.io.BufferedReader. (java.io.FileReader. fname))))</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

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.

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>

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>

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.

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>

Icon

<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> Note: str2toks is from the Icon Programming Library. To see the Icon language features available for the str2toks implementation please follow the external links.

Java

Some people prefer Scanner or BufferedReader, so a way with each is presented. <lang java>import java.util.Scanner; ... Scanner in = new Scanner(System.in);//stdin //new Scanner(new FileInputStream(filename)) for a file //new Scanner(socket.getInputStream()) for a network stream while(in.hasNext()){ String input = in.next(); //in.nextLine() for line-by-line //process the input here }</lang> Or <lang java>import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; ... try{ BufferedReader inp = new BufferedReader(new InputStreamReader(System.in));//stdin //new BufferedReader(new FileReader(filename)) for a file //new BufferedReader(new InputStreamReader(socket.getInputStream())) for a network stream while(inp.ready()){ String input = inp.readLine();//line-by-line only //in.read() for character-by-character //process the input here } } 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>

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>

Lua

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

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

end</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>

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>

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>

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>

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 PL/I> declare line character (200) varying;

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

do forever;

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

end; </lang>

Python

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 (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 R>lines <- readLines("file.txt")</lang>

REBOL

<lang REBOL>REBOL [ Title: "Basic Input Loop" Author: oofoe Date: 2009-12-06 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

Works with: oorexx

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>

Works with: ARexx

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

 l = readln(stdin)
 say l

end</lang>

Ruby

Ruby input streams are Enumerable objects like Arrays, so one can use the standard #each:

<lang ruby>stream.each do |line|

 # process line

end</lang>

One can open a new stream for read and have it automatically close when done:

<lang ruby>File.open(filename, "r") do |stream|

 stream.each do |line|
   # process line
 end

end</lang>

Or, <lang ruby>File.foreach(filename) do |line|

 # process line

end</lang>

Scala

Works with: Scala version 2.7

<lang scala>scala.io.Source.fromFile(filename).getLines.foreach {

 line => // do something

}</lang>

Works with: Scala version 2.8

<lang scala>scala.io.Source.fromPath(filename).getLines().foreach {

 line => // do something

}</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>

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>

Unicon

See Icon.

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>

UNIX Shell

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>

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>