reading from ifstream file gives wrong size [duplicate] - c++

This question already has answers here:
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Closed 8 years ago.
I have a .txt file containing 6291456 numbers and nothing else. After reading all out and push_back into a vector, the vector.size() function returns 6291457. Where does this additional element come from?
int disparity;
ifstream disparity_txt;
disparity_txt.open(path);
while(!disparity_txt.eof())
{
disparity_txt >> disparity;
vec_disparities.push_back(disparity);
}
cout << vec_disparities.size() << endl;
disparity_txt.close();

Don't use while(!disparity_txt.eof()) it does not do what you think (eof will only be set after the end of the stream is read, so typically the last iteration is wrong) :
Do :
while(disparity_txt >> disparity)
{
vec_disparities.push_back(disparity);
}

Using while (!in.eof()) is almost always wrong
Either stop looping when extracting a number from the stream fails (as shown in quantdev's answer) or use the standard library facilities meant for populating a container from a stream:
std::ifstream disparity_txt(path);
vec_disparities.assign(std::istream_iterator<int>(disparity_txt),
std::istream_iterator<int>());
You can open an fstream using its constructor, and the destructor will close it, you don't need explicit open and close calls.
In C++11 it's even simpler:
vec_disparities.assign(std::istream_iterator<int>{std::ifstream{path}}, {});

Related

`fin.get(ch);` reads last character twice while `ch=fin.get();` not inside `while(!fin.eof())` loop why? [duplicate]

This question already has answers here:
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Closed 1 year ago.
vicky.txt file
I was born in Hupari.
Code -1
#include <iostream>
#include<fstream>
int main()
{
char ch;
std::ifstream fin;
fin.open("vicky.txt", std::ios::in);
while (!fin.eof())
{
fin.get(ch);
std::cout<<ch;
}
fin.close();
return 0;
}
Output
I was born in Hupari..
Code -2
#include <iostream>
#include<fstream>
int main()
{
char ch;
std::ifstream fin;
fin.open("vicky.txt", std::ios::in);
while (!fin.eof())
{
ch=fin.get();
std::cout<<ch;
}
fin.close();
return 0;
}
Output
I was born in Hupari. 
Why while using fin.get(ch) it reads last character twice. On other hand ch=fin.get() reads correctly means reads last character one time only.
By the way also tell return type of fin.get(ch) ? and return type of fin.get() is char right ?
Both versions are wrong. See Why is iostream::eof inside a loop condition (i.e. while (!stream.eof())) considered wrong? for more details on how to correctly code reading loops.
Now, to the explanation what happens. The first version uses second overload of get(). This method leaves its argument unchanged if read fails (e.g. when end of file is reached) and sets flag. Thus, you print the last read character once again.
The second version uses first overload of get(). Because this version must return a character and cannot leave it unchanged like the other versions, it returns an int to be able to return special value EOF (which must not represent any valid character). EOF is typically equal to -1 (as int). Then, you implicitly cast it to char, which would make it equal to 255 (or keep it as -1, but 8 bits). You then print it. Depending on the code page used by the terminal, it could be ÿ char, non-breaking space or something else. Possibly, you have that non-breaking space character printed, or some other invisible or unprintable character.

Difference in use and efficiency when using ifstream [duplicate]

This question already has answers here:
The difference between using fstream constructor and open function
(4 answers)
Why do C++ standard file streams not follow RAII conventions more closely?
(5 answers)
Closed 1 year ago.
I am currently writing a program to read data from a big .csv file and wanted to know if there's any difference between using:
ifstream handle("filename");
and
ifstream handle;
archivo.open("filename", ios::in);
when opening the file.
I have tried both so far and the two have worked in reading the data to then store it in an STL container. I wanted to know if there's any concrete difference in use, efficiency and/or memory use.
Thanks in advance!
There is no differences between them.
ifstream handle("filename"); - you make ifstream type variable and then you open a file in one part of code;
ifstream handle; - you make ifstream type variable;
handle.open("filename", ios::in); - you open file in another part of code.
Second version can be useful when you need to have an ifsteam like a member of a class.
For example:
class myClass
{
public:
myClass(std::string str)
{
file.open(str);
}
private:
ifstream file;
...
};

C++ read from file only when there is more content [duplicate]

This question already has an answer here:
Read data from fstream
(1 answer)
Closed 3 years ago.
How can I check if there is more content in a text file in c++ and if there is continue to read it?
I am trying to read a some words from a text file but the number of words is not specified.
Check out this link here.
Also, std:: is a reference to the namespace of code you are calling. When you include a file that is in the standard libraries, such as string, vector, fstream, iostream, you need to either declare that your file will use the namespace std with using namespace std; OR you append std:: to the method or variable.
Use std::vector and std::string. Use a correct form of reading a file:
std::string word;
std::vector<std::string> word_database;
while (text_file >> word)
{
word_database.push_back(word);
}
std::cout << "Words read: " << word_database.size() << "\n";

Read the whole file, then overwrite all in same std::fstream [duplicate]

This question already has answers here:
How to truncate a file while it is open with fstream
(3 answers)
Closed 6 years ago.
Although I found a lot of stuff about std::fstream on SO, I still can't understand how it operates. Let's see this minimal example:
#include <fstream>
#include <string>
int main()
{
std::fstream fs{ "somefile.txt", std::fstream::out | std::fstream::in };
std::string line;
while (std::getline(fs, line))
{
// reads the whole file
}
// the purpose is to overwrite the whole file
fs.seekp(0, std::ios_base::beg); // moves at the beginning
fs << "Hello world!" << std::endl; // writes in the file
// possibly other read/write
}
This does not work, it seems that one cannot firstly read, and then write in the same stream according to everything I read about. I know the workaround that consists in closing the file, then opening it with the std::ios_base::trunc flag. However, that seems to be nonsensical: why is there such a limitation? Cannot we technically just overwrite the file after the reading?
The loop iterates until the fail bit gets set. Just clear() the flags prior to the seek:
fs.clear();
If you only want to overwrite the starting bit that is sufficient. If also want to truncate the stream I'd explicitly close() and open() it, where the open() would not set std::ios_base::in.
After reading the whole file, the fs is now in eof state. You need to clear the state so it can do following IO operations.

How to read a file in reverse order using C++ [duplicate]

This question already has answers here:
Read a file backwards?
(7 answers)
Closed 8 years ago.
How can I read a text file in reverse order (i.e. from eof) using C++?
Yes, but you basically have to do it manually.
The basic algorithm is as follows:
Seek to the end of the file with is.seekg(0, is.end)
Determine the file size with is.tellg()
Repeatedly seek backwards and read chunks of the file until you reach the front
If the file is small enough so the entire contents easily fit within memory, it will be both far faster and far easier to code to read the file forward into a string and then reversing that string after the fact.
If the contents won't fit in memory, you'll have to use nneonneo's solution. It would probably be best to turn off buffering.
Just use the seekg and related functions in istream class. Here is a working example. Tested.
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
ifstream in("file.txt");
// Get the length of the file
in.seekg(0, in.end);
int len = in.tellg();
// Start reading the file in reverse
char c;
while (len--)
{
in.seekg(len, in.beg);
in >> c;
cout << c;
}
}