CSV Data to Binary File

via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Aug 7 08:54:30 PDT 2014


On Thursday, 7 August 2014 at 15:14:00 UTC, TJB wrote:
> align(1) struct QuotesBin
> {
>   int qtim;
>   int bid;
>   int ofr;
>   int bidsiz;
>   int ofrsiz;
>   short mode;
>   char[1] ex;
>   char[4] mmid;
> }
>
> Thanks!

(You forgot to include the error. For other readers: It fails to 
compile with "template std.conv.toImpl cannot deduce function 
from argument types !(char[4])(string)" and similar error 
messages.)

This is caused by the two `char` arrays. `std.conv.to` cannot 
convert strings to fixed-size char arrays, probably because it's 
not clear what should happen if the input string is too long or 
too short.

Would it be a good idea to support this?

As a workaround, you could declare a second struct with the same 
members, but `ex` and `mmid` as strings, read your data into 
these, and assign it to the first structure:

import std.algorithm;
import std.csv;
import stdio = std.stdio;
import std.stream;

align(1) struct QuotesBinDummy
{
   int qtim;
   int bid;
   int ofr;
   int bidsiz;
   int ofrsiz;
   short mode;
   string ex;
   string mmid;
}

align(1) struct QuotesBin
{
   int qtim;
   int bid;
   int ofr;
   int bidsiz;
   int ofrsiz;
   short mode;
   char[1] ex;
   char[4] mmid;
}


void main()
{
   string infile = "temp.csv";
   string outfile = "temp.bin";
   Stream fin = new BufferedFile(infile);
   Stream fout = new BufferedFile(outfile, FileMode.Out);

   foreach(ulong n, char[] line; fin)
   {
     auto temp = csvReader!QuotesBinDummy(line).front;
     QuotesBin record;
     record.tupleof = temp.tupleof;
     fout.writeExact(&record, QuotesBin.sizeof);
   }

   fin.close();
   fout.close();
}

The line "record.tupleof = temp.tupleof;" will however fail with 
your example data, because the `ex` field includes a space in the 
CSV, and the last field is empty, but needs to be 4 chars long.


More information about the Digitalmars-d-learn mailing list