Looking for an equivalent to C++ std::getline in D

Stanislav Blinov via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri May 5 10:07:25 PDT 2017


On Friday, 5 May 2017 at 09:54:03 UTC, k-five wrote:
> Hi all.
> I have a simple command-line program utility in C++ that can 
> rename or remove files, based on regular expression.
> After finding D that is more fun than C++ is, I want to port 
> the code, but I have problem with this part of it:
>
>         std::getline( iss, match, delimiter );
>         std::getline( iss, substitute, delimiter );
>
> I need to read from iss ( = std::istringstream iss( argv[ 1 ] ) 
> and separate them by delimiter.
>
> Since the program gets the input from a user, and it can be 
> something like: 's/\d+[a-z]+@(?=\.)//g'  or '/[A-Za-z0-9]+//'
>
> So for: s/\d+[a-z]+@(?=\.)//g
> I need:
> s
> \d+[a-z]+@(?=\.)
> g
>
> and for: /[A-Za-z0-9]+/
> It should be:
> [A-Za-z0-9]+
>
> ---
>
> I tired ( std.string: split or format ) or ( std.regex split ). 
> In fact I need to read from a stream up to a delimiter.
>
> Does someone knows a way to do this in D? Thanks

So, you need to consume input one element at a time (delimited), 
dropping empty elements? Try std.algorithm.iteration splitter and 
filter:

auto advance(Range)(ref Range r)
{
     assert(!r.empty);
     auto result = r.front;
     r.popFront();
     return result;
}

void main(string[] args)
{
     import std.algorithm.iteration : splitter, filter;
     import std.range : empty;

     auto input = args[1].splitter('/').filter!"!a.empty"();

     import std.stdio : writeln;
     while (!input.empty)
         writeln(input.advance());
}

The advance() function reads the next delimited element and pops 
it from the range.


More information about the Digitalmars-d-learn mailing list