1

I have a little problem that i can't figure out.
I am trying to read a file into a buffer, My problem is that sometimes it adds a random character at the end of the text. (sometimes ? and abs etc.). So i wonder why that is happening. I haven't found any solution yet. The problem happens randomly, not every time i read the file.

    static char text[1024 * 16];
    std::ifstream File(FilePath, std::ios::in | std::ios::out | std::ios::binary | std::ios::ate);
    std::streamsize Size = File.tellg();
    File.seekg(0, std::ios::beg);
    char *string = new char[Size + 1];
    if (File.is_open()) 
    {
         File.read(string, Size);
         memset(text, 0, sizeof(text));
         snprintf(text, sizeof(text), "%s", string);

    }
    File.close();
    delete[] string;
  • Also see [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/q/5605125/608639). The Q&A discuss how to read data in a loop. Another one of interest is [How to read a binary file into a vector of unsigned chars](https://stackoverflow.com/q/15138353/608639). It looks at fast ways to read a file into a buffer. – jww Apr 22 '18 at 02:40

1 Answers1

4

Note that read() does not append a null terminator, it's just a raw binary read. In other words, the data is not a string, it's an array of bytes. You are probably trying to print it out or something, and it just keeps going until it sees a null terminator, potentially into uninitialized memory. You should manually allocate size + 1 and add the null terminator at the end.

A couple style notes: its not recommended to use variable names such as "File" or "Size". Its legal but bad practice, you can check out some popular style guides for more information (Google, LLVM)

Secondly, I would try to get this working with std::string rather than allocating memory manually, even on the stack. Check out reserve() and data()

Here's a cleaner example using std::string. More readable, easier to write, and just as efficient.

const char *somefile = "main.cpp";
std::ifstream fh(somefile, std::ios::in | std::ios::out | std::ios::binary |
                               std::ios::ate);
const size_t sz = fh.tellg();
if (sz <= 0) {
    // error handling here
}
fh.seekg(0, std::ios::beg);
// Initalizes a std::string with length sz, filled with null
std::string str = std::string(sz, '\0');
if (fh.is_open())
    fh.read(&str[0], sz);
fh.close();
std::cout << str << "[EOF]\n";
ricco19
  • 633
  • 4
  • 14