View mode: basic / threaded / horizontal-split · Log in · Help
October 07, 2012
std.csv.csvReader operating on File.byLine()
Hi,

To my understanding, The csv reader in std.csv is able to operate 
on any kind of input range. However I can only get it to work on 
strings. Please take a look at the following line of code. Did I 
make some mistake?

auto reader = csvReader!(Tuple!(int, int, 
float))(someFile.byLine());

When I try to compile that, the compiler output is:

main.d(24): Error: template std.csv.csvReader does not match any 
function template declaration
C:\D\dmd2\windows\bin\..\..\src\phobos\std\csv.d(283): Error: 
template std.csv.csvReader cannot deduce template function from 
argument types !(Tuple!(int,int,float))(ByLine!(char,char))
main.d(24): Error: template instance 
csvReader!(Tuple!(int,int,float)) errors instantiating template

As a workaround I could use readText, but that's dirty and won't 
work for large csv files.
October 07, 2012
Re: std.csv.csvReader operating on File.byLine()
On 10/07/2012 11:21 AM, Rene Zwanenburg wrote:
> Hi,
>
> To my understanding, The csv reader in std.csv is able to operate on any
> kind of input range.

The error message took me to the definition of the function. The 
template constraints require that the element type of the range must be 
a dchar:

// ...
  if(isInputRange!Range && is(ElementType!Range == dchar)
// ...

In your case, the element type of byLine() is a string. (I think.)

> However I can only get it to work on strings.
> Please take a look at the following line of code. Did I make some 
mistake?
>
> auto reader = csvReader!(Tuple!(int, int, float))(someFile.byLine());
>
> When I try to compile that, the compiler output is:
>
> main.d(24): Error: template std.csv.csvReader does not match any
> function template declaration
> C:\D\dmd2\windows\bin\..\..\src\phobos\std\csv.d(283): Error: template
> std.csv.csvReader cannot deduce template function from argument types
> !(Tuple!(int,int,float))(ByLine!(char,char))
> main.d(24): Error: template instance csvReader!(Tuple!(int,int,float))
> errors instantiating template
>
> As a workaround I could use readText, but that's dirty and won't work
> for large csv files.

If deneme.txt contains this:

1,2,3.5
6,7,8.5

This works:

import std.stdio;
import std.csv;
import std.typecons;

void main()
{
    auto someFile = File("deneme.txt");

    foreach (line; someFile.byLine()) {
        auto reader = csvReader!(Tuple!(int, int, float))(line);
        foreach (record; reader) {
            writeln(record);
        }
    }
}

Ali
October 07, 2012
Re: std.csv.csvReader operating on File.byLine()
Ah yes, I understand. Thanks.

For the sake of cleanliness (and Walter's article on component 
programming ;) ), is there a way to treat a file as an InputRange 
of characters? I think this is quite a common use case.

On Sunday, 7 October 2012 at 19:32:12 UTC, Ali Çehreli wrote:
> On 10/07/2012 11:21 AM, Rene Zwanenburg wrote:
> > Hi,
> >
> > To my understanding, The csv reader in std.csv is able to
> operate on any
> > kind of input range.
>
> The error message took me to the definition of the function. 
> The template constraints require that the element type of the 
> range must be a dchar:
>
> // ...
>   if(isInputRange!Range && is(ElementType!Range == dchar)
> // ...
>
> In your case, the element type of byLine() is a string. (I 
> think.)
>
> > However I can only get it to work on strings.
> > Please take a look at the following line of code. Did I make
> some mistake?
> >
> > auto reader = csvReader!(Tuple!(int, int,
> float))(someFile.byLine());
> >
> > When I try to compile that, the compiler output is:
> >
> > main.d(24): Error: template std.csv.csvReader does not match
> any
> > function template declaration
> > C:\D\dmd2\windows\bin\..\..\src\phobos\std\csv.d(283): Error:
> template
> > std.csv.csvReader cannot deduce template function from
> argument types
> > !(Tuple!(int,int,float))(ByLine!(char,char))
> > main.d(24): Error: template instance
> csvReader!(Tuple!(int,int,float))
> > errors instantiating template
> >
> > As a workaround I could use readText, but that's dirty and
> won't work
> > for large csv files.
>
> If deneme.txt contains this:
>
> 1,2,3.5
> 6,7,8.5
>
> This works:
>
> import std.stdio;
> import std.csv;
> import std.typecons;
>
> void main()
> {
>     auto someFile = File("deneme.txt");
>
>     foreach (line; someFile.byLine()) {
>         auto reader = csvReader!(Tuple!(int, int, float))(line);
>         foreach (record; reader) {
>             writeln(record);
>         }
>     }
> }
>
> Ali
October 07, 2012
Re: std.csv.csvReader operating on File.byLine()
On 10/07/2012 02:42 PM, Rene Zwanenburg wrote:

> For the sake of cleanliness (and Walter's article on component
> programming ;) ), is there a way to treat a file as an InputRange of
> characters? I think this is quite a common use case.

I've just discovered the undocumented byRecord:

Again, assuming that deneme.txt contains:

1,2,3.5
6,7,8.5

import std.stdio;

void main()
{
    auto someFile = File("deneme.txt");

    writeln(someFile.byRecord!(int, int, float)("%s,%s,%s"));
}

And there is std.algorithm.joiner:

    writeln(someFile.byLine.joiner);

There must be something more straightforward though. :)

Ali
October 07, 2012
Re: std.csv.csvReader operating on File.byLine()
On 08-Oct-12 01:42, Rene Zwanenburg wrote:
> Ah yes, I understand. Thanks.
>
> For the sake of cleanliness (and Walter's article on component
> programming ;) ), is there a way to treat a file as an InputRange of
> characters? I think this is quite a common use case.
>

IRC something along the lines of:

foreach(dchar ch; LockingTextReader(file))
{
...
}


-- 
Dmitry Olshansky
October 07, 2012
Re: std.csv.csvReader operating on File.byLine()
On Sunday, 7 October 2012 at 22:31:05 UTC, Dmitry Olshansky wrote:
> On 08-Oct-12 01:42, Rene Zwanenburg wrote:
>> Ah yes, I understand. Thanks.
>>
>> For the sake of cleanliness (and Walter's article on component
>> programming ;) ), is there a way to treat a file as an 
>> InputRange of
>> characters? I think this is quite a common use case.
>>
>
> IRC something along the lines of:
>
> foreach(dchar ch; LockingTextReader(file))
> {
> ...
> }

LockingTextReader is exactly what I was looking for. Thanks.
Top | Discussion index | About this forum | D home