PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label fstream. Show all posts
Showing posts with label fstream. Show all posts

Sunday, October 30, 2022

[FIXED] Why am I getting an std::bad_alloc error

 October 30, 2022     c++, eof, fstream     No comments   

Issue

I'm having an issue when running the code below. Every time I set the while loop to reach the .eof() it returns a std::bad_alloc

inFile.open(fileName, std::ios::in | std::ios::binary);

        if (inFile.is_open())
        {
            while (!inFile.eof())
            {
                read(inFile, readIn);
                vecMenu.push_back(readIn);
                menu.push_back(readIn);
                //count++;
            }

            std::cout << "File was loaded succesfully..." << std::endl;

            inFile.close();
        }

It runs fine if I set a predetermined number of iterations, but fails when I use the EOF funtion. Here's the code for the read function:

void read(std::fstream& file, std::string& str)
{
    if (file.is_open())
    {
        unsigned len;
        char *buf = nullptr;

        file.read(reinterpret_cast<char *>(&len), sizeof(unsigned));

        buf = new char[len + 1];

        file.read(buf, len);

        buf[len] = '\0';

        str = buf;

        std::cout << "Test: " << str << std::endl;

        delete[] buf;
    }
    else
    {
        std::cout << "File was not accessible" << std::endl;
    }
}

Any help you can provide is greatly appreciated. NOTE: I failed to mention that vecMenu is of type std::vector and menu is of type std::list


Solution

The main problems I see are:

  1. You are using while (!inFile.eof()) to end the loop. See Why is iostream::eof inside a loop condition considered wrong?.

  2. You are not checking whether calls to ifstream::read succeeded before using the variables that were read into.

I suggest:

  1. Changing your version of read to return a reference to ifstream. It should return the ifstream it takes as input. That makes it possible to use the call to read in the conditional of a loop.

  2. Checking whether calls to ifstream::read succeed before using them.

  3. Putting the call to read in the conditional of the while statement.

std::ifstream& read(std::fstream& file, std::string& str)
{
   if (file.is_open())
   {
      unsigned len;
      char *buf = nullptr;

      if !(file.read(reinterpret_cast<char *>(&len), sizeof(unsigned)))
      {
         return file;
      }

      buf = new char[len + 1];

      if ( !file.read(buf, len) )
      {
         delete [] buf;
         return file;
      }

      buf[len] = '\0';

      str = buf;

      std::cout << "Test: " << str << std::endl;

      delete[] buf;
   }
   else
   {
      std::cout << "File was not accessible" << std::endl;
   }

   return file;
}

and

inFile.open(fileName, std::ios::in | std::ios::binary);

if (inFile.is_open())
{
   std::cout << "File was loaded succesfully..." << std::endl;

   while (read(inFile, readIn))
   {
      vecMenu.push_back(readIn);
      menu.push_back(readIn);
      //count++;
   }

   inFile.close();
}


Answered By - R Sahu
Answer Checked By - Robin (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] why does ifstream read beyond eof? (even if no file is open) how to stop reading at eof?

 October 30, 2022     c++, eof, fstream, ifstream, io     No comments   

Issue

i was just testing some io safe checks with fstream and noticed i don't get any flags when seeking outside (i expected eof, but i realize flags are only set after io operations?) and when trying to read beyond the file size, i expected it to stop at eof, but it keeps on reading in from some unknown source. and lastly i noticed you don't even need to open a file. do i have to manually apply the math myself so it doesn't read past eof? and how/why/where is it reading past the file?

#include <iostream>
#include <fstream>

void checkErrors(std::ifstream& f){
    std::cout<<"FLAGS: ";
    if(f.good()) std::cout<<"good";
    if(f.rdstate() & f.badbit) std::cout<<"badbit ";
    if(f.rdstate() & f.eofbit) std::cout<<"eofbit ";
    if(f.rdstate() & f.failbit) std::cout<<"failbit ";
    std::cout<<std::endl;
}

int main(){
    std::ifstream file;
//  file.open("abc.txt"); // don't even have to open any file

    file.seekg(100, file.beg); // can seek outside file
    std::cout<<file.tellg()<<std::endl; // 100 (if open else) -1
    checkErrors(file); // FLAGS: good (if open else) failbit

    int size = 200;
    char* data = new char[size];

    file.read(data,size); // can read outside file
    checkErrors(file); // FLAGS: eofbit failbit (if open else) failbit

    for(int i=0; i<size; i++)std::cout<<data[i]; // PSModulePath=C:\Program Files\WindowsPowerShell\Modules;C:\Windows\...

}

Solution

why does ifstream read beyond eof?

I am sure it does not.
Are you asking why the bad() is not true after you move beyond the end?

(even if no file is open) how to stop reading at eof?

If you attempt to read beyond the end of a file then you will get an error. Moving beyond the end by itself is not enough. But an attempt to access the data after you are beyond the end should cause an error.

Well you see to have a bug is here:

file.read(data,size); // can read outside file
for(int i=0; i<size; i++)std::cout<<data[i]; // PSModulePath=C:\Program Files\WindowsPowerShell\Modules;C:\Windows\...

This should be written as:

if (file.read(data, size)) {
    // If you attempt to read and it works then you can print out
    // the data you read otherwise what is the point.

    // Also notice you can't gurantee that you got `size` bytes.
    // You should consult `gcount()` to get the number of characters read.

    for(int i = 0; i < file.gcount(); ++i) {
        std::cout << data[i];
    }
}


Answered By - Martin York
Answer Checked By - Pedro (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Why is failbit set when eof is found on read?

 October 30, 2022     c++, eof, fstream     No comments   

Issue

I've read that <fstream> predates <exception>. Ignoring the fact that exceptions on fstream aren't very informative, I have the following question:

It's possible to enable exceptions on file streams using the exceptions() method.

ifstream stream;
stream.exceptions(ifstream::failbit | ifstream::badbit);
stream.open(filename.c_str(), ios::binary);

Any attempt to open a nonexistent file, a file without the correct permissions, or any other I/O problem will results in exception. This is very good using an assertive programming style. The file was supposed to be there and be readable. If the conditions aren't met, we get an exception. If I wasn't sure whether the file could safely be opened, I could use other functions to test for it.

But now suppose I try to read into a buffer, like this:

char buffer[10];
stream.read(buffer, sizeof(buffer)); 

If the stream detects the end-of-file before filling the buffer, the stream decides to set the failbit, and an exception is fired if they were enabled. Why? What's the point of this? I could have verified that just testing eof() after the read:

char buffer[10];
stream.read(buffer, sizeof(buffer));
if (stream.eof()) // or stream.gcount() != sizeof(buffer)
    // handle eof myself

This design choice prevents me from using standard exceptions on streams and forces me to create my own exception handling on permissions or I/O errors. Or am I missing something? Is there any way out? For example, can I easily test if I can read sizeof(buffer) bytes on the stream before doing so?


Solution

Improving @absence's answer, it follows a method readeof() that does the same of read() but doesn't set failbit on EOF. Also real read failures have been tested, like an interrupted transfer by hard removal of a USB stick or link drop in a network share access. It has been tested on Windows 7 with VS2010 and VS2013 and on linux with gcc 4.8.1. On linux only USB stick removal has been tried.

#include <iostream>
#include <fstream>
#include <stdexcept>

using namespace std;

streamsize readeof(istream &stream, char *buffer, streamsize count)
{
    if (count == 0 || stream.eof())
        return 0;

    streamsize offset = 0;
    streamsize reads;
    do
    {
        // This consistently fails on gcc (linux) 4.8.1 with failbit set on read
        // failure. This apparently never fails on VS2010 and VS2013 (Windows 7)
        reads = stream.rdbuf()->sgetn(buffer + offset, count);

        // This rarely sets failbit on VS2010 and VS2013 (Windows 7) on read
        // failure of the previous sgetn()
        (void)stream.rdstate();

        // On gcc (linux) 4.8.1 and VS2010/VS2013 (Windows 7) this consistently
        // sets eofbit when stream is EOF for the conseguences  of sgetn(). It
        // should also throw if exceptions are set, or return on the contrary,
        // and previous rdstate() restored a failbit on Windows. On Windows most
        // of the times it sets eofbit even on real read failure
        (void)stream.peek();

        if (stream.fail())
            throw runtime_error("Stream I/O error while reading");

        offset += reads;
        count -= reads;
    } while (count != 0 && !stream.eof());

    return offset;
}

#define BIGGER_BUFFER_SIZE 200000000

int main(int argc, char* argv[])
{
    ifstream stream;
    stream.exceptions(ifstream::badbit | ifstream::failbit);
    stream.open("<big file on usb stick>", ios::binary);

    char *buffer = new char[BIGGER_BUFFER_SIZE];

    streamsize reads = readeof(stream, buffer, BIGGER_BUFFER_SIZE);

    if (stream.eof())
        cout << "eof" << endl << flush;

    delete buffer;

    return 0;
}

Bottom line: on linux the behavior is more consistent and meaningful. With exceptions enabled on real read failures it will throw on sgetn(). On the contrary Windows will treat read failures as EOF most of the times.



Answered By - ceztko
Answer Checked By - Katrina (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing