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

Sunday, October 30, 2022

[FIXED] How does ifstream's eof() work?

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

Issue

#include <iostream>
#include <fstream>

int main() {
    std::fstream inf( "ex.txt", std::ios::in );
    while( !inf.eof() ) {
        std::cout << inf.get() << "\n";
    }
    inf.close();
    inf.clear();
    inf.open( "ex.txt", std::ios::in );
    char c;
    while( inf >> c ) {
        std::cout << c << "\n";
    }
    return 0;
}

I'm really confused about eof() function. Suppose that my ex.txt's content was:

abc

It always reads an extra character and shows -1 when reading using eof(). But the inf >> c gave the correct output which was 'abc'? Can anyone help me explain this?


Solution

-1 is get's way of saying you've reached the end of file. Compare it using the std::char_traits<char>::eof() (or std::istream::traits_type::eof()) - avoid -1, it's a magic number. (Although the other one is a bit verbose - you can always just call istream::eof)

The EOF flag is only set once a read tries to read past the end of the file. If I have a 3 byte file, and I only read 3 bytes, EOF is false, because I've not tried to read past the end of the file yet. While this seems confusing for files, which typically know their size, EOF is not known until a read is attempted on some devices, such as pipes and network sockets.

The second example works as inf >> foo will always return inf, with the side effect of attempt to read something and store it in foo. inf, in an if or while, will evaluate to true if the file is "good": no errors, no EOF. Thus, when a read fails, inf evaulates to false, and your loop properly aborts. However, take this common error:

while(!inf.eof())  // EOF is false here
{
    inf >> x;      // read fails, EOF becomes true, x is not set
    // use x       // we use x, despite our read failing.
}

However, this:

while(inf >> x)  // Attempt read into x, return false if it fails
{
    // will only be entered if read succeeded.
}

Which is what we want.



Answered By - Thanatos
Answer Checked By - Mildred Charles (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] How to make getline play nice with ios::exceptions?

 October 30, 2022     c++, eof, exception, getline, ifstream     No comments   

Issue

I am trying to use an ifstream that I need to be able to loop through using getline but would like to have throw exceptions using ios::exceptions:

#include <iostream>
#include <fstream>
#include <string>

int main()
{
    std::ifstream f;
    f.exceptions( std::ifstream::failbit | std::ifstream::badbit );

    try {
        f.open("data/all-patents.dat", std::ifstream::in);
    }
    catch (std::ifstream::failure e) {
        std::cout << "Caught exception opening: " << e.what() << "\n";
    }
    
    std::string l;
    while (!std::getline(f, l).eof()) {
        // do something
    }

}

But when getline hits EOF, it throws an exception:

terminate called after throwing an instance of 'std::__ios_failure'
  what():  basic_ios::clear: iostream error

Program received signal SIGABRT, Aborted.
0x00007ffff7ad8615 in raise () from /usr/lib/libc.so.6

Which I can confirm by catching it:

#include <iostream>
#include <fstream>
#include <string>

int main()
{
    std::ifstream f;
    f.exceptions( std::ifstream::failbit | std::ifstream::badbit );

    try {
        f.open("data/all-patents.dat", std::ifstream::in);
    }
    catch (std::ifstream::failure e) {
        std::cout << "Caught exception opening: " << e.what() << "\n";
    }
    
    std::string l;
    try {
        while (!std::getline(f, l).eof()) {
            // do something
        }
    }
    catch (std::ifstream::failure e) {
        std::cout << "Caught exception reading: " << e.what() << "\n";
    }

}

Output: Caught exception reading: basic_ios::clear: iostream error

Why does EOF throw an exception despite me not using ifstream::eofbit in ios::exceptions's mask? Is there a way I can keep using ios::exceptions without having to enclose my while loop in a try?


Solution

You turn on throwing exceptions on failbit and later when std::getline(f, l) fails to extract any characters it will set failbit which is triggering the exception.



Answered By - Ted Lyngmo
Answer Checked By - Katrina (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, October 29, 2022

[FIXED] How to read in from a file word by word and assign those words to a struct?

 October 29, 2022     c++, eof, file, ifstream, struct     No comments   

Issue

In my project I have a .txt file that has the number of books at the top, and then title of a book and its author separated by a space, so for example:

1
Elementary_Particles Michel_Houllebecq

I then have a struct for the book object

struct book {
    string title;
    string author;
};

There is a book array of these book objects to since there are multiple books and authors. What I need to do is to read in these word by word and assign the title to book.title and the author to book.author. This is what I have so far:

void getBookData(book* b, int n, ifstream& file) { //n being the number at the top of the file
    int count = 0;
    string file_string;
    while(!file.eof() && count != n-1) {
       while (file >> file_string) {
           b[count].title = file_string;
           b[count].author = file_string;
           count++;
   }
}

When I run this with these outputs:

cout << book[0].title << endl;
cout << book[0].author << endl;

I get:

Elementary_Particles
Elementary_Particles

Basically it is only taking the first word. How do I make it so that the first word will be assigned to book.title and the next one after to book.author?

Thank you


Solution

In this piece of code

while (file >> file_string) {
      b[count].title = file_string;
      b[count].author = file_string;
      count++;
}

you read one word and assign the same value to title and author, don't expect the compiler to guess your intentions ;)

Some additional hints and ideas:

while(!file.eof() is not what you want, instead put the input operations into the loop condition. And you can skip the intermediate string and read directly into title/author:

void getBookData(book* b, int n, ifstream& file) {
    int count = 0;
    while((file >> b[count].title >> b[count].author) && count != n-1) {
        count++;
    }
}


Answered By - churill
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to read file containing a list of integers with an unknown size

 October 29, 2022     arrays, c++, eof, ifstream     No comments   

Issue

I want to read from a file containing an unknown list of 4 integers each. So each line of the file contain something like this"12.0 43.0 19.0 77.0" I thought of using a 2 dimensional array but I don't know the size of the file because its a very big file. I ended up reading each line as a string and used a "while(!in_file.eof())" so I can reach the end of the file but the problem is, I need to get the numbers individually form each line.

Here's a snippet of my code


Solution

You don't need to know how many lines are in your file or how many numbers are in each line.

Use std::vector< std::vector< int > > to store data. If in each line, integers are separated with a space, you can iterate a string of integers and add them one by one to a vector:

#include <iostream>
#include <string>    
#include <stream>
#include <vector>
using namespace std;

int main()
{
    string textLine = "";
    ifstream MyReadFile("filename.txt");
    vector<vector<int>> main_vec;

    // Use a while loop together with the getline() function to read the file line by line
    while (getline(MyReadFile, textLine)) {
    
        vector<int> temp_vec; // Holdes the numbers in a signle line
        int number = 0;

        for (int i = 0, SIZE = textLine.size(); i < SIZE; i++) {

            if (isdigit(textLine[i])) {
                number = number * 10 + (textLine[i] - '0');
            }
            else { // It's a space character. One number was found:
                temp_vec.push_back(number);
                number = 0; // reset for the next number
            }
        }

        temp_vec.push_back(number); // Also add the last number of this line.
        main_vec.push_back(temp_vec); 
    }

    MyReadFile.close();

    // Print Result:
    for (const auto& line_iterator : main_vec) {
        for (const auto& number_iterator : line_iterator) {
            cout << number_iterator << " ";
        }

        cout << endl;
    }
}

Hint: This code works for only integers. For floats, you can easily identify the indices of spaces in each line, get substring of your textLine, and then convert this substring to a float number .



Answered By - ArashV
Answer Checked By - Mildred Charles (PHPFixing Admin)
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