www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std.csv.csvReader operating on File.byLine()

reply "Rene Zwanenburg" <renezwanenburg gmail.com> writes:
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.
Oct 07 2012
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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 

 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
Oct 07 2012
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
Oct 07 2012
prev sibling parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
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
Oct 07 2012
prev sibling next sibling parent "Rene Zwanenburg" <renezwanenburg gmail.com> writes:
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

 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

 auto reader = csvReader!(Tuple!(int, int,

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

 main.d(24): Error: template std.csv.csvReader does not match

 function template declaration
 C:\D\dmd2\windows\bin\..\..\src\phobos\std\csv.d(283): Error:

 std.csv.csvReader cannot deduce template function from

 !(Tuple!(int,int,float))(ByLine!(char,char))
 main.d(24): Error: template instance

 errors instantiating template

 As a workaround I could use readText, but that's dirty and

 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

Oct 07 2012
prev sibling parent "Rene Zwanenburg" <renezwanenburg gmail.com> writes:
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.
Oct 07 2012