I'm new to C++, so this should be a fairly basic question.
Assume I have bunny.voxel.ply file. This file is written out in binary, with the first 4 bytes corresponding to the (integer) sampling resolution, res, and the next 4 x res x res x res bytes corresponding to the (single precision) floating point values.
I want to read these values into 3D array voxel. My current code:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE* fp = fopen( "bunny.voxel.ply" , "rb" );
if (fp==NULL) {fputs ("File error",stderr); exit (1);}
int res;
fread( &res , 1 , sizeof(int) , fp );
float *voxel = new float[res*res*res];
fread(voxel , res * res * res , sizeof(float) , fp );
fclose( fp );
std::cout << "Hello, World!" << std::endl;
return 0;
}
seems to only read the last value.
Any suggestions on how I can modify this read all values?
The Parameters of fread are
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
Thus you probably should exchange the order of your 2nd and 3rd parameter:
int count = res*res*res;
float *voxel = new float[count];
fread(voxel, sizeof(float), count, fp);
By accident the last value was in the correct memory position so that you could identify it.
Related
Given the same path argument to FILE *fopen(const char *path, const char *mode), is fopen() guaranteed to return the same FILE* value?
E.g., is the output of the following code guaranteed to always be two pointers of the same value?
#include <iostream>
#include <cstdio>
int foo( FILE* fp )
{
std::cout << fp << std::endl;
fclose(fp);
fp = fopen( "foo.txt", "w+" );
std::cout << fp << std::endl;
}
int main( int argc, char* arv[] )
{
FILE* fp = fopen( "foo.txt", "a" );
fwrite( "hello", 5, 1, fp );
foo( fp );
fwrite( "goodbye", 7, 1, fp );
fclose(fp);
return 0;
}
I.e. I'm wondering if foo()'s manipulation of its local fp is invalidating main()'s. But this code, compiled, always outputs the same FILE* value twice, implying main()'s is still valid, even if foo() is working on a local copy instead of a reference.
For some context, this is a simplification of a bug I'm chasing at work: the equivalent of the second fwrite() above sometimes returns 0, and I'm trying to track down why. It looks like fwrite()'s error reporting is limited to ferror() and feof(), but the above sample code, compiled, always outputs the same pointer value twice, implying the code is okay, and I'm left unclear why either the ferror() or feof() conditions would be hit.
I am trying to write a simple program that reads a file by encapsulating functions like open, lseek, pread.
My file for test contains:
first second third forth fifth sixth
seventh eighth
my main function that tries to read 20 bytes with offset 10 from the file:
#include <iostream>
#include "CacheFS.h"
using namespace std;
int main(int argc, const char * argv[]) {
char * filename1 = "/Users/Desktop/File";
int fd1 = CacheFS_open(filename1);
//read from file and print it
void* buf[20];
CacheFS_pread(fd1, &buf, 20, 10);
cout << (char*)buf << endl;
}
implementation of the functions that the main is using:
int CacheFS_open(const char *pathname)
{
mode_t modes = O_SYNC | 0 | O_RDONLY;
int fd = open(pathname, modes);
return fd;
}
int CacheFS_pread(int file_id, void *buf, size_t count, off_t offset)
{
off_t seek = lseek(file_id, offset, SEEK_SET);
off_t fileLength = lseek(file_id, 0, SEEK_END);
if (count + seek <= fileLength) //this case we are not getting to the file end when readin this chunk
{
pread(file_id, &buf, count, seek);
} else { //count is too big so we can only read a part of the chunk
off_t size = fileLength - seek;
pread(file_id, &buf, size, seek);
}
return 0;
}
My main function prints this to the console:
\350\366\277_\377
I would expect it to print some values from the file itself, and not some numbers and slashes that represenet something I do not really understand.
Why does this happen?
The following changes will make your program work:
Your buffer has to be an existent char array and your CacheFS_pread function is called without the address operator & then. Also use the buffer size minus 1 because the pread function will override the terminating \0 because it's just read n bytes of the file. I use a zero initialized char array here so that there will be a null terminating \0 at least at the end.
char buf[20] = { '\0' }; // declare and initialize with zeros
CacheFS_pread(fd1, buf, sizeof(buf) - 1, 10);
Your function header should accept only a char pointer for typesafety reasons.
int CacheFS_pread(int file_id, char* buf, size_t count, off_t offset)
Your pread call is then without the address operator &:
pread(file_id, buf, count, seek);
Output: nd third forth fift because buffer is just 20!
Also I would check if your calculations and your if statements are right. I have the feeling that it's not exactly right. I would also recomment to use the return value of pread.
I have a float buffer with the data of the ppm file. The buffer[0][0] is the 1st element and the buffer[3*width*height][0] is the last element of the data.
Buffer has elements like this. 1st = 117 2st= 135 3st = 122. It's red, green and blue.
The point is to write this data into a binary file!
I try this, getHeight() returns the Height and getWidth() the width of the data.
ofstream output(filename, ios::out | ios::binary);
output.write((char *)buffer, img.getHeight() * img.getWidth() * 3);
Also i try this, for i=0 to i=3*height*width
fp = fopen(filename, "wb");
fwrite(reinterpret_cast<char*>(&buffer[i][0]), 1, 3*height*width, fp);
A float is 4 bytes each.
fwrite() doesn't know of the type you're writing, so for the size, you need to also multiply by the size of each element.
fwrite(reinterpret_cast<char*>(&buffer[i][0]), 1, 3*height*width * sizeof(float), fp);
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main() {
ofstream out("blah.txt");
float val = 10.0f;
out << fixed << setprecision(5) << val << endl;
out.close();
return 0;
}
I am having the matlab code to read binary data:
**nfft = 256;
navg = 1024;
nsamps = navg * nfft;
f_s = 8e6;
nblocks = floor(10 / (nsamps / f_s));
for i = 1:nblocks
nstart = 1 + (i - 1) * nsamps;
fid = fopen('data.dat'); % binary data and 320 MB
fseek(fid,4 * nstart,'bof');
y = fread(fid,[2,nsamps],'short');
x = complex(y(1,:),y(2,:));
end**
it will give me complex data with the length up to 8e6.
I am trying to write C++ to do the same function what matab does, but I could not get all the data or they are not the same original.
Can anyone help for ideals?
Here is my C++ code which I am working on.
Thank you so much.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <complex>
#include <vector>
#include <stdlib.h>
struct myfunc{
char* name;
};
int main() {
FILE* r = fopen("data.bin", "rb");
fread( w, sizeof(int), 30, r);
fread(&c, sizeof(myfunc),1,r);
for(int i=0; i < 30; i++){
cout<< i << ". " << w[i] << endl;
}
return 0;
}
Based on comment
the c I called from the struct myfunc and the w is the vector. so they are will be : int w[40]; myfunc c;
fread(&c, sizeof(myfunc),1,r);
will read one pointer's worth of data from file stream r into c. This will not be particularly useful as whatever address myfunc.name pointed at when the file was written will almost certainly be invalid when the file is read back.
Solution: Serialize myfunc.name when writing to the file and deserialize it when reading. Insufficient information is in the question to suggest how best to do this. I would store the string Pascal style and prepend the length of myfunc.name to make reading it back easier:
int len = strlen(myfunc.name);
fwrite(&len, sizeof(len), 1, outfile); // write length
fwrite(myfunc.name, len, 1, outfile); // write string
and read it
int len;
fread(&len, sizeof(len), 1, infile); // read length
myfunc.name = new char[len+1]; // size string with space for terminator
fwrite(myfunc.name, len, 1, infile); // read string
myfunc.name[len] = '\0'; // terminate string
Note the above code completely ignores endian and error handling.
Hi please some one help me
I've two process say some X and Y.
X and Y both have the following information
typedef enum {
HEALTHY=1,
FAULTY=2,
CHANGE=3,
ERROR=4
} MsgTypeT;
typedef struct {
char role[16];
char state[16];
char info[256];
} InfoT;
typedef struct {
MsgTypeT type;
int size;
InfoT *data;
} MsgT;
Here the condition is that if process Y sends an information process X will read it
So i used fifo between x and y
Y has a function write buffer which writes to fifo and code is as following
int write_buffer(HA_DEVMON_MsgT const* send)
{
char* dest = buffer;
memcpy( dest, &send->type, sizeof( MsgTypeT ));
dest += sizeof(MsgTypeT);
memcpy( dest, &send->size, sizeof( int ));
dest += sizeof(int);
memcpy( dest, send->data, sizeof( InfoT ));
dest += sizeof(InfoT);
int byteCount = write( this->fifo_fd, buffer, dest - buffer );
if ( byteCount != dest - buffer ) {
cout<<"Error in writing ";
}
return byteCount == dest - buffer ? 0 : -1;
}
I think it's writing perfectly because cout statements are working fine also when tried to output nbytes it gave 512bytes have been written
Now when X tries to read it's giving null values for role and state also size its giving 6441568
Its only giving MsgTypeT correct other values are null :(
The code is as follows--- I'm doing something wrong please correct it
int readMsg(MsgT *msg)
{
int rCode=0, nbytes=0;
char buffer[512]={0};
nbytes = read(this->get_handle(), buffer, sizeof(buffer));
if (nbytes < 0) {
cout<<"error in read";
rCode=-1;
}
if (rCode == 0) {
char *p_src = (char *)buffer;
mempcpy(&msg->type, p_src, sizeof(MsgTypeT));
p_src+=sizeof(MsgTypeT);
mempcpy(&msg->size, p_src, sizeof(int));
p_src+=sizeof(int);
msg->data = new InfoT(); //allocating memory (needed or not???)
mempcpy(msg->data, p_src, sizeof(InfoT));
p_src+=sizeof(InfoT);
}
return rCode;
}
In readMsg, your last mempcpy writes to msg, not to the
InfotT you just allocated.
Also, but I suppose you know this: this is only guaranteed to
work if both processes were compiled with the same compiler,
using the same options. (In practice, it's likely to work if
the underlying system defines its API in terms of C, which is
the case for Windows and Unix.)
EDIT:
Further: you have the same problem when writing. You write
sizeof(InfoT) (288) bytes, but you write the pointer (and then
a lot of garbage), not the data it's pointing to.
And you increment the pointer into the MsgT object. This is
likely not to work, if there is any padding. What you really
have to do is:
int
write_buffer( MsgT const* data )
{
char buffer[512] = {}; // Or better yet, std::vector<char>
char* dest = buffer;
memcpy( dest, &data->type, sizeof( MsgTypeT ) );
dest += sizeof( MsgTypeT );
memcpy( dest, &data->size, sizeof( int ) );
dest += sizeof( int );
memcpy( dest, &data->data, sizeof( InfoT ) );
dest += sizeof( InfoT );
int byteCount = write( fifo_fd, buffer, dest - buffer );
if ( byteCount != dest - buffer ) {
std::cerr << "Error in write" << std::endl;
}
return byteCount == dest - buffer ? 0 : -1;
}
and the opposite when reading.
And once again, this will only really work for two processes on
the same machine, compiled with the same compiler using the same
options. A better solution would probably be to define
a protocol, with a defined representation of integers, strings,
etc., format your output to that representation, and parse it
for your input. That way, it will still work even if one of the
processes is 64 bits, and the other 32.