Как D способ написать это? - PullRequest
5 голосов
/ 03 января 2012

Я написал эту программу на C , а также на erlang

На практике я пытался переписать на D. Друг также написал ее на D, но написал по-другому

Шаги просты.Псевдокод:

While not end of file:
   X = Read ulong from file and covert to little endian
   Y = Read X bytes from file into ubyte array
   subtract 1 from each byte in Y
   save Y as an ogg file

Моя попытка D:

import std.file, std.stdio, std.bitmanip, std.conv, core.stdc.stdio : fread;
void main(){
  auto file = File("./sounds.pk", "r+");
  auto fp = file.getFP();
  ulong x;
  int i,cnt;
  while(fread(&x, 8, 1, fp)){
     writeln("start");
     x=swapEndian(x);
     writeln(x," ",cnt++,"\n");
     ubyte[] arr= new ubyte[x]; 
     fread(&arr, x, 1, fp);
     for(i=0;i<x;i++) arr[i]-=1;
     std.file.write("/home/fold/wak_oggs/"~to!string(cnt)~".ogg",arr);
  }   
}

Кажется, я не могу просто использовать fread для обр.sizeof равен 16, и это дает ошибку сегментации, когда я добираюсь до вычитающей части.Я не могу автоматически выделить статический массив, или, по крайней мере, я не знаю как.Я также не могу использовать malloc, потому что он дает мне ошибки, когда я пытаюсь разыграть void *, когда я перебираю байты.Как бы вы написали это, или что я мог бы сделать лучше?

Ответы [ 2 ]

5 голосов
/ 03 января 2012

Опять же, почему вы ожидаете, что сможете прочитать весь блок в один массив (размер которого в байтах умещается в 64-битной длине (возможно, больше, чем несколько петабайт))? Я сделал этот комментарий и в другом вопросе

используйте цикл для копирования содержимого

writeln("start");
x=swapEndian(x);
writeln(x," ",cnt++,"\n");
ubyte[1024*8] arr=void; //the buffer 
            //initialized with void to avoid auto init (or declare above the for)
ubyte b; //temp buff
File out = File("/home/fold/wak_oggs/"~to!string(cnt)~".ogg", "wb");

b=fp.rawRead(arr[0..x%$]);//make it so the buffer can be fully filled each loop
foreach(ref e;b)e-=1;//the subtract 1 each byte loop
out.rawWrite(b);
x-=b.length;
while(x>0 && (b=fp.rawRead(arr[])).length>0){//loop until x becomes 0
    foreach(ref e;b)e-=1;
    out.rawWrite(b);
    x-=b.length;
}

Я использую rawRead и rawWriteчитать и писать

3 голосов
/ 03 января 2012

arr не является указателем и не преобразуется в указатель, как в C и C ++.

Если вы хотите указатель на начало массива, используйте arr.ptr.

Чтобы выделить статический массив, вы используете:

ubyte[N] arr;

Тем не менее, N должна быть постоянной времени компиляции (как в C и C ++), так что здесь она может быть бесполезна.

...