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