byLine(n)?

Cym13 via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jun 11 01:33:16 PDT 2017


On Sunday, 11 June 2017 at 05:36:08 UTC, helxi wrote:
> I was writing a program that reads and prints the first nth 
> lines to the stdout:
>
> import std.stdio;
>
> void main(string[] args)
> {
>     import std.algorithm, std.range;
>     import std.conv;
>     stdin.byLine.take(args[1].to!ulong).each!writeln;
> }
>
> As far as I understand the stdin.byLine.take(args[1].to!ulong) 
> part reads all the lines written in stdin.
> What if I want to make byLine read only and only first nth line?
>
> stdin.byLine(args[1].to!ulong).each!writeln;
>
> Obviously the code above won't work. Is there any efficient 
> workaround?

Ok, if I read you right you are writing to stdin and want first 
to print the first args[1] lines, then to do other things with 
the other lines of stdin.

If you use byLine you will not read all the lines of stdin, but 
you will lose a line. From there I see three possibilities:

1) If you control the input, add a limit line (if you want to 
take 2 then the third line will be lost):

import std.conv;
import std.stdio;
import std.range;
import std.algorithm;

void main(string[] args) {
     auto limit = args.length > 1 ? args[1].to!ulong : 2;

     writefln("First %d lines", limit);
     stdin.byLineCopy.take(limit).each!writeln;
     writeln("Next lines");
     stdin.byLineCopy.each!writeln;
}



2) Read all stdin and separate those you want to print from the 
others later:

import std.conv;
import std.stdio;
import std.range;
import std.algorithm;

void main(string[] args) {
     // I used byLineCopy because of the buffer reuse issue
     auto input = stdin.byLineCopy;
     auto limit = args.length > 1 ? args[1].to!ulong : 2;

     writefln("First %d lines", limit);
     input.take(limit).each!writeln;
     writeln("Next lines");
     input.each!writeln;
}

3) Do not use byLine for the first lines in order to control how 
much you read.

import std.conv;
import std.stdio;
import std.range;
import std.algorithm;

void main(string[] args) {
     auto limit = args.length > 1 ? args[1].to!ulong : 2;

     writefln("First %d lines", limit);
     foreach (line ; 0 .. limit) {
         // I use write here because readln keeps the \n by default
         stdin.readln.write;
     }
     writeln("Next lines");
     stdin.byLine.each!writeln;
}


There are other options but I think these are worth considering 
first.


More information about the Digitalmars-d-learn mailing list