Question

I've got a class project to make a webserver in c++. Everything's been going OK until I got to the point where I needed to host images or pdfs, at which point the files were corrupted. Doing some more digging, I realized that all the corrupted images had null characters before the end.

That brings me to my question. I have a char* which I've read these files to, and I know the length of the file. I'm pretty positive that the entire file is being read in (code below), but I don't know how to print it out or send it. How can I tell C++ that I want to send the first X characters following the char*? (I'm sure the answer is somewhere here or on the web, I just can't seem to phrase my question in the right way to find the answer)

ifstream myfile (path.c_str() , ios::in|ios::binary|ios::ate);
ifstream::pos_type size = myfile.tellg();
cout << size << endl;
fileSize = (int) size;
fileToReturn = new char [size];
myfile.seekg (0, ios::beg);
myfile.read (fileToReturn, size);
myfile.close();

cout << "file read\n"<< fileToReturn << endl;

For a plain text file, this would output fine. For the PDF, it only prints the first part of the file (the part before the first null character). How do I get it to print out the whole file?

EDIT: To clarify, my end goal is to send this over the web, not re-save the file.

// reply is string with all my headers and everything set.
// fileToReturn is my char*, and fileSize is the int with how long it should be  
char* totalReply = new char [reply.length() + fileSize+1];
strcpy(totalReply, reply.c_str());
strcat(totalReply, fileToReturn);
send(client, totalReply, reply.length() + fileSize, 0);
Was it helpful?

Solution

The issue is that ostream& operator<< (ostream& out, const char* s ); expects s to be a null-terminated ASCII string. So it stops as soon as it encounters a NUL character. If you really want to write all data to the console, use `ostream& write ( const char* s , streamsize n ), like this:

cout.write(fileToReturn, size);

The issue is the same for strcat: it stops after the first NUL character. So concatenate using memcpy:

memcpy(totalReply, reply.c_str(), reply.size()+1);
memcpy(totalReply+reply.size()+1, fileToReturn, fileSize )

But you tagged this question as C++, so why not do it like this:

ifstream myfile (path.c_str() , ios::in|ios::binary|ios::ate);
vector<char> totalReply;
totalReply.insert(buffer.end(), reply.begin(), reply.end());
// need a NUL character here?: totalReply.push_back('\0');
totalReply.insert(buffer.end(), istream_iterator(myfile), istream_iterator());
send(client, &totalReply[0], totalReply.size(), 0);

OTHER TIPS

you fail to mention how you open the file, make sure you have opened in binary mode otherwise seek et all will not work properly with new line characters.

i.e. myfile.open( "yourfile", ios::binary|ios::in )

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top