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