-
May 11th, 2016, 04:30 AM
#1
eof not working properly?
so I got two questions with this code, first lets work on the efficacy..making it work, then may be a more efficient implementation can be suggested...
there is a header _row.h
Code:
# pragma once
struct _row
{
int c1;
int c2;
int c3;
};
and a class build wheel
Code:
class MakeWheel
{
private : std::string text ;
public :
MakeWheel (std::string textfile );
public:
std::vector<_row> buildWheel();
};
buildWheel is fed with a text file which contains 3 separated two digits integer on every line...
the aim is to load every line into a struct object _row..place them in a vector which can be used else where in the bigger application...
code of buildWheel()
Code:
MakeWheel :: MakeWheel (std::string textfile)
{text = textfile;}
std::vector<_row> MakeWheel :: buildWheel ()
{
std::string temp, stemp;
std::vector<_row> hold;
std::ifstream f(text) ;
if(f.is_open())
{
while ( !f.eof() )
{
_row *rowpt = new _row ;
std::getline(f, temp);
stemp = temp.substr(0, 2);
rowpt->c1 = std::stoi(stemp, nullptr, 0);
stemp = temp.substr(3,2);
rowpt->c2 = std::stoi(stemp, nullptr, 0);
stemp = temp.substr(6,2);
rowpt->c3 = std::stoi(stemp, nullptr, 0);
hold.push_back(*rowpt);
delete rowpt;
}
f.close ();
}
else std::cout<<"could not open file to take in raw values for filtering"<<std::endl;
return hold ;
}
Ok so everything compiles fine..
but when I run the code I get an out of range error, running it through the debugger I noticed that the problem was in the while brace and to be precise with the eof..after the last line ..getline continues to read the empty space after the last line which I think is loaded into temp and of course being an empty string I get an error with string.substr ...
or at least this is what I understood with the debugger...
so the first solution will be to try to make getline not read in an empty string or better still eof flag should really go up after the last line of digits has been read...which for a strange reason is not happening...
thanks to all who pass by...
-
May 11th, 2016, 05:28 AM
#2
Re: eof not working properly?
Generally, this method is always wrong (since eof() does not become true until after
an attempt has been made to read past eof):
Code:
while ( !f.eof() )
{
std::getline(f, temp);
Normally, the coding would be:
Code:
while ( getline(f,temp) )
{
-
May 11th, 2016, 05:39 AM
#3
Re: eof not working properly?
Originally Posted by TheLionKing
but when I run the code I get an out of range error, running it through the debugger I noticed that the problem was in the while brace and to be precise with the eof..after the last line ..getline continues to read the empty space after the last line which I think is loaded into temp and of course being an empty string I get an error with string.substr ...
or at least this is what I understood with the debugger...
You understood correctly: the problem is that the EOF flag is only set when end of file is reached (or there is an error, but that is presumably not the case here). But end of file is only reached when getline attempts to read, and finds that it has reached the end of the file. Therefore, you should use the return value of getline to control the loop instead of using the eof member function:
Code:
while (std::getline(f, temp))
{
_row *rowpt = new _row ;
stemp = temp.substr(0, 2);
rowpt->c1 = std::stoi(stemp, nullptr, 0);
stemp = temp.substr(3,2);
rowpt->c2 = std::stoi(stemp, nullptr, 0);
stemp = temp.substr(6,2);
rowpt->c3 = std::stoi(stemp, nullptr, 0);
hold.push_back(*rowpt);
delete rowpt;
}
Incidentally, I do not see why you need manual memory management here. It looks like you just need to write:
Code:
while (std::getline(f, temp))
{
auto row_obj = _row{};
row_obj.c1 = std::stoi(temp.substr(0, 2), nullptr, 0);
row_obj.c2 = std::stoi(temp.substr(3, 2), nullptr, 0);
row_obj.c3 = std::stoi(temp.substr(6, 2), nullptr, 0);
hold.push_back(row_obj);
}
Or maybe even:
Code:
while (std::getline(f, temp))
{
hold.push_back({
std::stoi(temp.substr(0, 2), nullptr, 0),
std::stoi(temp.substr(3, 2), nullptr, 0),
std::stoi(temp.substr(6, 2), nullptr, 0),
});
}
-
May 11th, 2016, 06:29 AM
#4
Re: eof not working properly?
Or even using emplace_back with stream extraction. Consider
Code:
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const string vfn = "vec.txt";
struct _row
{
int c1;
int c2;
int c3;
_row(int cc1, int cc2, int cc3) : c1(cc1), c2(cc2), c3(cc3) {}
};
vector<_row> Wheel;
int main()
{
ifstream ifs(vfn);
if (!ifs.is_open()) {
cout << "Cannot open input file " << vfn << endl;
return 1;
}
int v1, v2, v3;
char ch;
while (ifs >> v1 >> ch >> v2 >> ch >> v3)
Wheel.emplace_back(v1, v2, v3);
if (!ifs.eof()) {
cout << "error reading file!" << endl;
return 2;
}
for (const auto& w : Wheel)
cout << w.c1 << " " << w.c2 << " " << w.c3 << endl;
}
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
May 11th, 2016, 06:42 AM
#5
Re: eof not working properly?
Originally Posted by laserlight
Incidentally, I do not see why you need manual memory management here. It looks like you just need to write:
thanks will implement your method
-
May 11th, 2016, 06:56 AM
#6
Re: eof not working properly?
thanks to you all who responeded!!!
-
May 11th, 2016, 10:51 AM
#7
Re: eof not working properly?
Incidentally, I do not see why you need manual memory management here. It looks like you just need to write:
hello man, thanks but there is a trick you used here that is new to me..wow this one right here..
so what is the technical name of this trick? so just by assigning a variable to a class/struct name with curly braces and ; an object of type of the class/struct is created? nice!
do we ever stop learning???
-
May 11th, 2016, 11:02 AM
#8
Re: eof not working properly?
Master 2kaud can you shed more light on the way you designed the struct please? I mean what about the
_row(int cc1, int cc2, int cc3) : c1(cc1), c2(cc2), c3(cc3) {}
inside the struct? what is the technical name of this move too? can you explain more please..thanks..
-
May 11th, 2016, 11:20 AM
#9
Re: eof not working properly?
Any way guys, the solution you gave didn't work! but thanks soo much for the different implementations you gave...that was soo useful...
the solution didn't work because even by using
while (std::getline(f, temp) ) , getling was still reading in an empty string at the end...so I solved it by adding this other condition...
whilte(std::getline(f,temp) && temp.size() > 0) ;
-
May 11th, 2016, 11:30 AM
#10
Re: eof not working properly?
Originally Posted by TheLionKing
while (std::getline(f, temp) ) , getling was still reading in an empty string at the end...so I solved it by adding this other condition...
Oh, if there is indeed a blank line at the end in the input, then of course just checking the return value of getline will not suffice. However, this points to another problem: you rely on std::stoi to validate the input, but you did not catch the possible std::invalid_argument exception. What if it was not a blank line, but nonetheless was invalid input?
-
May 11th, 2016, 11:36 AM
#11
Re: eof not working properly?
ok laserlight, can you please say something about the question I asked you earlier on? about this
auto row_obj = _row{};
-
May 11th, 2016, 11:53 AM
#12
Re: eof not working properly?
Originally Posted by TheLionKing
Master 2kaud can you shed more light on the way you designed the struct please? I mean what about the
inside the struct? what is the technical name of this move too? can you explain more please..thanks..
in c++, struct is just like a class and can have constructors and a destructor. The only difference is that in a struct all is public by default and in a class all is private by default. So that line is just a constructor for _row that takes 3 ints and assigns them to c1, c2 and c3 using a member initializer list. See https://msdn.microsoft.com/en-us/library/s16xw1a8.aspx member lists.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
May 11th, 2016, 11:58 AM
#13
Re: eof not working properly?
-
May 11th, 2016, 11:59 AM
#14
Re: eof not working properly?
Originally Posted by TheLionKing
Any way guys, the solution you gave didn't work! but thanks soo much for the different implementations you gave...that was soo useful...
the solution didn't work because even by using
while (std::getline(f, temp) ) , getling was still reading in an empty string at the end...so I solved it by adding this other condition...
whilte(std::getline(f,temp) && temp.size() > 0) ;
Note that the code in my post #4 ignores blank lines so having an empty line at the end (or even multiple blank lines during the file) doesn't effect it's operation.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
May 11th, 2016, 12:06 PM
#15
Re: eof not working properly?
I admit I didn't implement your solution master 2kaud, will look into that..thanks for re bringing it to my attention
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|