What is the D way to write this?

血红的双手。 提交于 2021-01-27 06:19:27

问题


I wrote this program in C and also in erlang

To practice I tried to rewrite in D. A friend also wrote it in D but wrote it differently

The steps are simple. Pseudocode:

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

My D attempt:

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);
  }   
}

It seems I can't just use fread on arr. sizeof is 16 and it gives segmentation fault when I get to the subtracting part. I can't auto alloc a static array, or at least I don't know how. I also can't seem to use malloc because it gives me errors when I try to cast the void* when I loop through the bytes. How would you write this, or, what could I do better?


回答1:


again why do you expect to be able to read in the entire chunk into a single array (which size in bytes fits in a 64 bit long (possibly more that several petabytes) I made that comment in the other question as well

use a loop to copy the contents

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;
}

I'm using rawRead and rawWrite to read and write




回答2:


arr is not a pointer, and does not convert to a pointer like it does in C and C++.

If you want a pointer to the start of the array, use arr.ptr.

To allocate a static array, you use:

ubyte[N] arr;

However, N must be a compile time constant (just like in C and C++), so it may not be much use here.



来源:https://stackoverflow.com/questions/8706466/what-is-the-d-way-to-write-this

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!