问题
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