input range from stdin

krzaq via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Sep 18 02:21:16 PDT 2014


On Wednesday, 17 September 2014 at 18:05:36 UTC, Ali Çehreli 
wrote:
> On 09/17/2014 08:30 AM, krzaq wrote:
>> On Wednesday, 17 September 2014 at 14:37:21 UTC, Marc Schütz 
>> wrote:
>>> On Wednesday, 17 September 2014 at 12:44:00 UTC, krzaq wrote:
>>>> I'd like to have something similar to C++'s
>>>> std::istream_iterator<int>(std::cin)
>>>>
>>>> Is it possible? I'm relatively indifferent to efficiency of 
>>>> the
>>>> solution.
>>>
>>> import std.stdio;
>>> import std.algorithm;
>>> import std.conv;
>>> writeln(stdin.byLine.map!(to!int));
>>
>> What happens if I later have some strings that I want to read 
>> from the
>> same line?
>>
>> How can I use the resultant range with std.fill?
>>
>> My idea doesn't seem to work: 
>> http://dpaste.dzfl.pl/130e14c927f3
>
> The following worked:
>
> import std.stdio;
> import std.format;
> import std.exception;
> import std.string;
> import std.algorithm;
>
> struct Data
> {
>     int i;
>     string s;
> }
>
> Data toData(char[] line)
> {
>     int i;
>     string s;
>     auto slice = line;
>
>     const items = formattedRead(line, " %s %s", &i, &s);
>     enforce (items == 2, format("Incomplete line: %s", slice));
>
>     return Data(i, s);
> }
>
> void main()
> {
>     auto data = stdin.byLine.map!toData;
>     writeln(data);
> }
>
> I could not get it work with fill because fill requires 
> specific types of ranges, which neither the destination nor the 
> source were. For example, I wanted to use std.array.Appender 
> but fill wants an InputRange. Also, the source is not a 
> ForwardRange because it is consuming from stdin.
>
> However, it is easy to make an array with std.array.array:
>
>     import std.array;
>     writeln(data.array);
>
> Ali

Thank you for your reply.

That's not what I wanted. Maybe I should explain instead of 
expecting you to divine my intentions, though :) I am trying to 
rewrite the following program in D--making it more elegant: 
http://melpon.org/wandbox/permlink/ff42FoyKgqJK60sm

As you can see, I can have one input line consisting of n words 
and then n integers and I can read from it easily. My question 
whether stdin.byLine allows me to do this remains unanswered (or 
I failed to understand the answer), although I am not hopeful.

As to std.fill: I find myself surprised. Any idea why the input 
range is considered incorrect? In any case, should 
integers[0..$].fill(...) not make it correct, at least in regards 
to the first argument? Docs have an example with int[]

I expected my D code to look more or less like the following:

words.fill(stdin.by!string);
integers.fill(stdin.by!int);
zip(integers,words).map!(p => p[1][p[0]]).join.writeln;



More information about the Digitalmars-d-learn mailing list