The milk man
The milk man

Reputation: 164

Error loading file with ifstream - only a small part is loaded

I am trying to open a file and put it into a string. My code is:

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main () {
  streampos size;
  char * memblock;

  ifstream file ("C:\\a\\test.snt", ios::in | ios::binary | ios::ate);
  if (file.is_open()){

    size = file.tellg();
    memblock = new char [size];
    file.seekg (0, ios::beg);
    file.read (memblock, size);
    file.close();

    std::string someString(memblock);

    if(file.bad()){cout << "Bad\n";}
    if(file.fail()){cout << "Fail\n";}

    delete[] memblock;
  }else{ cout << "Unable to open file";}

  return 0;
}

The problem is it does not load most of the only a small part as such "ýýýý««««««««îþîþ". The file I am trying to when opened with notepad++ looks like such Notepad++
(source: gyazo.com)

Upvotes: 1

Views: 409

Answers (2)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385405

std::string someString(memblock);

Here you're using the string constructor that takes a const char* and reads until the first null byte, as it has no other way to know how many bytes to read.

  • In your binary file, one of those null bytes is appearing quite early.
  • If your file had no null bytes, the string constructor would just keep reading even beyond your allocated memory, causing danger and calamity.

Instead, use the string constructor that reads precisely the number of bytes you tell it to, regardless of what the bytes' values are:

std::string someString(memblock, size);

Upvotes: 1

simonc
simonc

Reputation: 42215

std::string someString(memblock);

should be

std::string someString(memblock, size);

The former version of the constructor creates someString treating memblock as a C-style string which terminates at the first byte with value 0. This may end up creating too short a string; for other file contents, you might end up reading beyond the memory you allocated.

The latter version creates someString using the full contents of memblock, including any 0 bytes.

Upvotes: 2

Related Questions