Input loop: Difference between revisions

From Rosetta Code
Content added Content deleted
No edit summary
Line 3: Line 3:
=={{header|Ada}}==
=={{header|Ada}}==
This example reads in a text stream from standard input line by line and writes the output to standard output.
This example reads in a text stream from standard input line by line and writes the output to standard output.
<ada>
<lang ada>
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Text_Io; use Ada.Text_Io;


Line 22: Line 22:
end loop;
end loop;
end Read_Stream;
end Read_Stream;
</ada>
</lang>


=={{header|ALGOL 68}}==
=={{header|ALGOL 68}}==
Line 37: Line 37:
SKIP
SKIP
)
)
For multi page files, each page is seekable with ''<code>PROC set = (REF FILE file, INT page, line, char)VOID: ~</code>''. This allows rudimentary random access where each new page is effectively a new record.
For multi page files, each page is seekable with ''<tt>PROC set = (REF FILE file, INT page, line, char)VOID: ~</tt>''. This allows rudimentary random access where each new page is effectively a new record.
main:(
main:(
PROC raise logical file end = (REF FILE f) BOOL: ( except logical file end );
PROC raise logical file end = (REF FILE f) BOOL: ( except logical file end );
Line 63: Line 63:


=={{header|C}}==
=={{header|C}}==
<c>#include <stdio.h>
<lang c>#include <stdio.h>


#define MAX_LEN 20
#define MAX_LEN 20
Line 89: Line 89:
}
}
}
}
</c>
</lang>


=={{header|C++}}==
=={{header|C++}}==
The following functions store the words resp. lines in a vector. Of course, instead arbitrary processing of the words could be done.
The following functions store the words resp. lines in a vector. Of course, instead arbitrary processing of the words could be done.
<cpp>#include <istream>
<lang cpp>#include <istream>
#include <string>
#include <string>
#include <vector>
#include <vector>
Line 116: Line 116:
// store the line in the vector
// store the line in the vector
lines.push_back(line);
lines.push_back(line);
}</cpp>
}</lang>


An alternate way to read all words into a vector is to use iterators:
An alternate way to read all words into a vector is to use iterators:


<cpp>#include <istream>
<lang cpp>#include <istream>
#include <string>
#include <string>
#include <iterator>
#include <iterator>
Line 130: Line 130:
std::copy(std::istream_iterator<std::string>(is), std::istream_iterator<std::string>(),
std::copy(std::istream_iterator<std::string>(is), std::istream_iterator<std::string>(),
std::back_inserter(words));
std::back_inserter(words));
}</cpp>
}</lang>


For arbitrary processing, replace std::copy with std::for_each or std::transform calling an appropriate function (or function object).
For arbitrary processing, replace std::copy with std::for_each or std::transform calling an appropriate function (or function object).
Line 136: Line 136:
=={{header|D}}==
=={{header|D}}==
{{libheader|Tango}}
{{libheader|Tango}}
<d>import tango.io.Console;
<lang d>import tango.io.Console;
import tango.text.stream.LineIterator;
import tango.text.stream.LineIterator;


Line 143: Line 143:
// do something with each line
// do something with each line
}
}
}</d>
}</lang>
{{libheader|Tango}}
{{libheader|Tango}}
<d>import tango.io.Console;
<lang d>import tango.io.Console;
import tango.text.stream.SimpleIterator;
import tango.text.stream.SimpleIterator;


Line 152: Line 152:
// do something with each word
// do something with each word
}
}
}</d>
}</lang>


Note that foreach variables 'line' and 'word' are transient slices. If you need to retain them for later use, you should .dup them.
Note that foreach variables 'line' and 'word' are transient slices. If you need to retain them for later use, you should .dup them.
Line 199: Line 199:
=={{header|Java}}==
=={{header|Java}}==
Some people prefer <tt>Scanner</tt> or <tt>BufferedReader</tt>, so a way with each is presented.
Some people prefer <tt>Scanner</tt> or <tt>BufferedReader</tt>, so a way with each is presented.
<java>import java.util.Scanner;
<lang java>import java.util.Scanner;
...
...
Scanner in = new Scanner(System.in);//stdin
Scanner in = new Scanner(System.in);//stdin
Line 207: Line 207:
String input = in.next(); //in.nextLine() for line-by-line
String input = in.next(); //in.nextLine() for line-by-line
//process the input here
//process the input here
}</java>
}</lang>
Or
Or
<java>import java.io.BufferedReader;
<lang java>import java.io.BufferedReader;
import java.io.IOException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InputStreamReader;
Line 224: Line 224:
} catch (IOException e) {
} catch (IOException e) {
//There was an input error
//There was an input error
}</java>
}</lang>


=={{header|OCaml}}==
=={{header|OCaml}}==
<ocaml>let rec read_lines ic =
<lang ocaml>let rec read_lines ic =
try let line = input_line ic in
try let line = input_line ic in
line :: read_lines ic
line :: read_lines ic
with End_of_file ->
with End_of_file ->
[]</ocaml>
[]</lang>


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


<ocaml>let read_line ic =
<lang ocaml>let read_line ic =
try Some (input_line ic)
try Some (input_line ic)
with End_of_file -> None
with End_of_file -> None
Line 247: Line 247:
in
in
loop []
loop []
;;</ocaml>
;;</lang>


Or with a higher order function:
Or with a higher order function:


<ocaml>let read_lines f ic =
<lang ocaml>let read_lines f ic =
let rec loop () =
let rec loop () =
try f(input_line ic); loop()
try f(input_line ic); loop()
Line 259: Line 259:


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


=={{header|Perl}}==
=={{header|Perl}}==
The angle brackets operator ( <code><...></code> ) reads one line at a time from a filehandle in scalar context:
The angle brackets operator ( <tt><...></tt> ) reads one line at a time from a filehandle in scalar context:
<perl>open FH, "< $filename" or die "can't open file: $!";
<lang perl>open FH, "< $filename" or die "can't open file: $!";
while (my $line = <FH>) {
while (my $line = <FH>) {
chomp $line; # removes trailing newline
chomp $line; # removes trailing newline
# process $line
# process $line
}
}
close FH or die "can't close file: $!";</perl>
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:
Or you can get a list of all lines when you use it in list context:
<perl>@lines = <FH>;</perl>
<lang perl>@lines = <FH>;</lang>


=={{header|PHP}}==
=={{header|PHP}}==
<php>$fh = fopen($filename, 'r');
<lang php>$fh = fopen($filename, 'r');
if ($fh) {
if ($fh) {
while (!feof($fh)) {
while (!feof($fh)) {
Line 281: Line 281:
}
}
fclose($fh);
fclose($fh);
}</php>
}</lang>


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


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


=={{header|Python}}==
=={{header|Python}}==
Python file objects can be iterated like lists:
Python file objects can be iterated like lists:


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


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


with open(filename, 'r') as f:
with open(filename, 'r') as f:
for line in f:
for line in f:
pass # process line, includes newline</python>
pass # process line, includes newline</lang>


You can also get lines manually from a file:
You can also get lines manually from a file:
<python>line = my_file.readline() # returns a line from the 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</python>
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.
This does not mix well with the iteration, however.




When (multiple) filenames are given on the command line:
When (multiple) filenames are given on the command line:
<python>import fileinput
<lang python>import fileinput
for line in fileinput.input():
for line in fileinput.input():
pass # process line, includes newline</python>
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.
The fileinput module can also do inplace file editing, follow line counts, and the name of the current file being read etc.


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


<ruby>stream.each do |line|
<lang ruby>stream.each do |line|
# process line
# process line
end</ruby>
end</lang>


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


<ruby>File.open(filename, "r") do |stream|
<lang ruby>File.open(filename, "r") do |stream|
stream.each do |line|
stream.each do |line|
# process line
# process line
end
end
end</ruby>
end</lang>


=={{header|UnixPipes}}==
=={{header|UnixPipes}}==

Revision as of 15:24, 3 February 2009

Task
Input loop
You are encouraged to solve this task according to the task description, using any language you may know.

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:

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.

AWK

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

{ print $0 }

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 store the words resp. lines in a vector. Of course, instead arbitrary processing of the words could be done. <lang cpp>#include <istream>

  1. include <string>
  2. include <vector>

// word by word void read_words(std::istream& is, std::vector<std::string>& words) {

 std::string word;
 while (is >> word)
 {
   // store the word in the vector
   words.push_back(word);
 }

}

// line by line: void read_lines(std::istream& is, std::vector<std::string>& lines) {

 std::string line;
 while (std::getline(is, line))
 {
   // store the line in the vector
   lines.push_back(line);
 }</lang>

An alternate way to read all words into a vector is to use iterators:

<lang cpp>#include <istream>

  1. include <string>
  2. include <iterator>
  3. include <algorithm>
  4. include <vector>

void read_words(std::istream& is, std::vector<std::string>& words) {

 std::copy(std::istream_iterator<std::string>(is), std::istream_iterator<std::string>(),
           std::back_inserter(words));

}</lang>

For arbitrary processing, replace std::copy with std::for_each or std::transform calling an appropriate function (or function object).

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.

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 ;

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

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

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>

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>

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>

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>

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.

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>

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


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