Input loop

From Rosetta Code

Jump to: navigation, search
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.

Contents

[edit] Ada

This example reads in a text stream from standard input line by line and writes the output to standard output.

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;

[edit] ALGOL 68

For file consisting of just one page - a typical linux/unix file:

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
)

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.

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
)

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.

[edit] 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

[edit] AWK

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

{ print $0 }

or, more idiomatic:

1

[edit] AutoHotkey

This example reads the text of a source file line by line and writes the output to a destination file.

Loop, Read, Input.txt, Output.txt
{
FileAppend, %A_LoopReadLine%`n
}

[edit] C

#include <stdio.h>
 
#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. */
 
#define Str(x) #x
#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 */
}
}

[edit] C++

The following functions send the words resp. lines to a generic output iterator

 
#include <istream>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#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;
}
 
 

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

 
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);
}
 

[edit] C#

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();
}
}
}

[edit] Clojure

(defn basic-input [fname]
(line-seq (java.io.BufferedReader. (java.io.FileReader. fname))))

[edit] Common 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))))

[edit] D

Library: Tango

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

Library: Tango

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

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

[edit] Eiffel

Works with: Eiffel Studio version 6.6

 
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
 
 

[edit] F#

Using a sequence expression:

 
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() }
 

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

[edit] Factor

"file.txt" utf8 [ [ process-line ] each-line ] with-file-reader

[edit] Forth

Works with: GNU 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 ;

[edit] 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)

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

[edit] gnuplot

The following gnuplot script echoes standard input to standard output line-by-line until the end of the stream.

!cat

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.

[edit] 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.

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

[edit] 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

[edit] Icon and Unicon

[edit] Icon

link str2toks
# 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

Library: Icon Programming Library See str2toks

[edit] Unicon

This Icon solution works in Unicon.

[edit] J

Script "read-input-until-eof.ijs":

#!/Applications/j602/bin/jconsole
NB. read input until EOF
((1!:1) 3)(1!:2) 4
exit ''

Example:

$ ./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 ...

[edit] Java

Some people prefer Scanner or BufferedReader, so a way with each is presented.

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
}

Or

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
}

[edit] 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

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);
}

[edit] Logo

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
while [not eof?] [print readline]

[edit] Lua

lines = {}
str = io.read()
while str do
table.insert(lines,str)
str = io.read()
end

[edit] MAXScript

this function will read a file line by line.

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
)

[edit] Modula-3

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.

[edit] 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();
};
}
}
}
 

[edit] OCaml

let rec read_lines ic =
try let line = input_line ic in
line :: read_lines ic
with End_of_file ->
[]

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

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 []
;;

Or with a higher order function:

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))

[edit] 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

[edit] 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;

[edit] Perl

The angle brackets operator ( <...> ) reads one line at a time from a filehandle in scalar context:

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: $!";

Or you can get a list of all lines when you use it in list context:

@lines = <FH>;

Or a simpler program for lines of files entered as command line arguments or standard input:

while (<>) {
# $_ contains a line
}

[edit] PHP

$fh = fopen($filename, 'r');
if ($fh) {
while (!feof($fh)) {
$line = rtrim(fgets($fh)); # removes trailing newline
# process $line
}
fclose($fh);
}

Or you can get an array of all the lines in the file:

$lines = file($filename);

Or you can get the entire file as a string:

$contents = file_get_contents($filename);

[edit] PicoLisp

This reads all lines in a file, and returns them as a list of lists

(in "file.txt"
(make
(until (eof)
(link (line)) ) ) )

[edit] 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;
 

[edit] PureBasic

File objects can be read bytewise, characterwise (ASCII or UNICODE), floatwise, doublewise, integerwise, linewise ...

 
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

[edit] Python

Python file objects can be iterated like lists:

my_file = open(filename, 'r')
try:
for line in my_file:
pass # process line, includes newline
finally:
my_file.close()

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

from __future__ import with_statement
 
with open(filename, 'r') as f:
for line in f:
pass # process line, includes newline

You can also get lines manually from a file:

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

This does not mix well with the iteration, however.


When (multiple) filenames are given on the command line:

import fileinput
for line in fileinput.input():
pass # process line, includes newline

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

[edit] R

Note that read.csv and read.table provide alternatives for files with 'dataset' style contents.

lines <- readLines("file.txt")

[edit] 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

[edit] REXX

Works with: oorexx

Reading line by line from the standard input using linein and lines did not work.

do while stream(stdin, "State") <> "NOTREADY"
call charout ,charin(stdin)
end

Works with: ARexx

/* -- AREXX -- */
do until eof(stdin)
l = readln(stdin)
say l
end

[edit] Ruby

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

stream.each do |line|
# process line
end

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

File.open(filename, "r") do |stream|
stream.each do |line|
# process line
end
end

Or,

File.foreach(filename) do |line|
# process line
end

[edit] Scala

Works with: Scala version 2.7

scala.io.Source.fromFile(filename).getLines.foreach {
line => // do something
}

Works with: Scala version 2.8

scala.io.Source.fromPath(filename).getLines().foreach {
line => // do something
}

[edit] Slate

(File newNamed: 'README') reader sessionDo: [| :input | input lines do: [| :line | inform: line]].

[edit] Smalltalk

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

[edit] SNOBOL4

loop  output = input :s(loop)
end

[edit] Tcl

set fh [open $filename]
while {[gets $fh line] != -1} {
# process $line
}
close $fh

For “small” files, it is often more common to do this:

set fh [open $filename]
set data [read $fh]
close $fh
foreach line [split $data \n] {
# process line
}

[edit] UnixPipes

the pipe 'yes XXX' produces a sequence

read by lines

yes 'A B C D ' | while read x ; do echo -$x- ; done

read by words

yes 'A B C D ' | while read -d\  a ; do echo -$a- ; done

[edit] UNIX Shell

When there is something to do with the input, here is a loop:

while read line ; do
# examine or do something to the text in the "line" variable
echo "$line"
done

The following echoes standard input to standard output line-by-line until the end of the stream.

cat < /dev/stdin > /dev/stdout

Since cat defaults to reading from standard input and writing to standard output, this can be further simplified to the following.

cat

[edit] Visual Basic .NET

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

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
Personal tools
Support