File.readln

S readln(S = string)(dchar terminator = '\n') if (isSomeString!S) @safe

Read line from the file handle and return it as a specified type.

This version manages its own read buffer, which means one memory allocation per call. If you are not retaining a reference to the read data, consider the File.readln(buf) version, which may offer better performance as it can reuse its read buffer.

Parameters

STemplate parameter; the type of the allocated buffer, and the type returned. Defaults to string.
terminatorLine terminator (by default, '\n').

Note

String terminators are not supported due to ambiguity with readln(buf) below.

Returns

The line that was read, including the line terminator character.

Throws

StdioException on I/O error, or UnicodeException on Unicode conversion error.

Example:

// Reads `stdin` and writes it to `stdout`.
import std.stdio;

void main()
{
   string line;
   while ((line = stdin.readln()) !is null)
       write(line);
}

size_t readln(C)(ref C[] buf, dchar terminator = '\n') if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum)) @safe

Read line from the file handle and write it to buf[], including terminating character.

This can be faster than line = File.readln() because you can reuse the buffer for each call. Note that reusing the buffer means that you must copy the previous contents if you wish to retain them.

Parameters

bufBuffer used to store the resulting line data. buf is enlarged if necessary, then set to the slice exactly containing the line.
terminatorLine terminator (by default, '\n'). Use newline for portability (unless the file was opened in text mode).

Returns

0 for end of file, otherwise number of characters read.

The return value will always be equal to buf.length.

Throws

StdioException on I/O error, or UnicodeException on Unicode

conversion error.

Example:

// Read lines from `stdin` into a string
// Ignore lines starting with '#'
// Write the string to `stdout`
import std.stdio;

void main()
{
   string output;
   char[] buf;

   while (stdin.readln(buf))
   {
       if (buf[0] == '#')
           continue;

       output ~= buf;
   }

   write(output);
}

This method can be more efficient than the one in the previous example because stdin.readln(buf) reuses (if possible) memory allocated for buf, whereas line = stdin.readln() makes a new memory allocation for every line.

For even better performance you can help readln by passing in a large buffer to avoid memory reallocations. This can be done by reusing the largest buffer returned by readln:

Example:

// Read lines from `stdin` and count words
import std.array, std.stdio;

void main()
{
   char[] buf;
   size_t words = 0;

   while (!stdin.eof)
   {
       char[] line = buf;
       stdin.readln(line);
       if (line.length > buf.length)
           buf = line;

       words += line.split.length;
   }

   writeln(words);
}

This is actually what byLine does internally, so its usage is recommended if you want to process a complete file.

size_t readln(C, R)(ref C[] buf, R terminator) if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum) && isBidirectionalRange!R && is(typeof(terminator.front == dchar.init))) @safe

ditto