Input loop

From Rosetta Code
Revision as of 11:51, 23 March 2008 by rosettacode>Dirkt (Added Haskell example)
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.

C++

The following functions store the words resp. lines in a vector. Of course, instead arbitrary processing of the words could be done.

#include <istream>
#include <string>
#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);
  }
}

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

#include <istream>
#include <string>
#include <iterator>
#include <algorithm>
#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));
}

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

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

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 netowrk stream
		while(inp.ready()){
			String input = inp.readLine();//line-by-line only
			//process the input here
		}
} catch (IOException e) {
	//There was an input error
}