By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,196 Members | 1,682 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,196 IT Pros & Developers. It's quick & easy.

where does open open the file?

P: n/a
I'm having problem reading from the beginning of a file.
Here is the code (more or less)


ifstream codefin;
ofstream codefout;

while (not_annoyed)
{
codefout.open("bar");
// write to bar, works fine
codefout.bar();
system("command to change bar to foo");

codefin.open("foo");
if (!codefin.is_open())
cout<<"ERROR: couldn't open foo for reading"<<endl;

cout<<codefin.tellg();
codefin.seekg(0,ios::beg);
cout<<codefin.tellg();

if (codefin.eof())
cout<<"FRACK!\n";
while (!codefin.eof())
getline(codefin,text);
codefin.close();
}
The files foo and bar are there and they look alright, but when I run the
program, at the second run I get the FRACK output. The file foo is not
opened in the beginning. I add the seekg/tellg commands to see, but there
is nothing but -1 and -1 printed.

What have I done wrong?

Jan 21 '06 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Gunnar G wrote:
I'm having problem reading from the beginning of a file.
Here is the code (more or less)


ifstream codefin;
ofstream codefout;

while (not_annoyed)
{
codefout.open("bar");
// write to bar, works fine
codefout.bar();
You mean,

coutfout.close();
system("command to change bar to foo");

codefin.open("foo");
if (!codefin.is_open())
cout<<"ERROR: couldn't open foo for reading"<<endl;

cout<<codefin.tellg();
codefin.seekg(0,ios::beg);
cout<<codefin.tellg();

if (codefin.eof())
cout<<"FRACK!\n";
while (!codefin.eof())
getline(codefin,text);
codefin.close();
}
The files foo and bar are there and they look alright, but when I run
the program, at the second run I get the FRACK output. The file foo
is not opened in the beginning. I add the seekg/tellg commands to
see, but there is nothing but -1 and -1 printed.

What have I done wrong?


I am not sure. Post _real_ code, *complete* and *compilable*. Even
though 'system' is OS-specific, you could simply explain what you mean
by "change bar to foo". Rename? Why not use 'std::rename'? Anyway...

V
Jan 21 '06 #2

P: n/a
> I am not sure. Post _real_ code, *complete* and *compilable*.

Here it is then.

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <string>
using namespace std;

int main(int argc, char* argv[])
{
if (argc!=2) {
cout<<"Usage: "<<argv[0]<<" latex_fil.tex"<<endl<<endl;
return 0;
}

bool codemode=false; // found code?
string line;
string texline;
string tmp="/tmp/.Big_secret_I_love_emacs_and_I_hate_vim.cpp";
string tmptex=tmp+".tex";
string command="highlight -A -L -t 4 -I -f -r -q -i "+tmp+" -o "+tmptex;

vector<string> source;
vector<string> latex_out; // the resulting latex file
string codefile;
ofstream codefout;
ifstream codefin;
ifstream fin(argv[1]);
if (!fin.is_open())
{
cout<<"Could not open the file "<<argv[1]<<endl<<endl;
return -1;
}
cout<<" Opening "<<argv[1]<<endl;
while (!fin.eof())
{
getline(fin,line);
if (line!="\\begin{KODcpp}" && line!= "\\end{KODcpp}")
{
if (!codemode)
latex_out.push_back(line);
else
{
// write to the file
if (line[line.size()-1]=='\\' && line[line.size()-2]=='\\')
line=line.substr(0,line.size()-2);
codefout<<line<<endl;
}
}
else
{
if (!codemode)
{ // open file and write
cout<<" Creating code in "<<tmp<<endl;
codefout.open(tmp.c_str());
if (!codefout.is_open())
{
cout<<"ERROR: couldn't open "<<tmp<<" for writing"<<endl;
}
latex_out.push_back("\\begin{KODcpp}");
codemode=true;
}
else
{ // close file and run highlight and then insert it
codefout.close();
codemode=false;
system(command.c_str());
system("cat /tmp/.Big_secret_I_love_emacs_and_I_hate_vim.cpp");
cout<<endl<<endl;
system("cat /tmp/.Big_secret_I_love_emacs_and_I_hate_vim.cpp.tex");
codefin.open(tmptex.c_str());
if (!codefin.is_open())
{
cout<<"ERROR: couldn't open "<<tmptex<<" for reading"<<endl;
}
cout<<codefin.tellg();
codefin.seekg(0,ios::beg);
cout<<codefin.tellg();
if (codefin.eof()) cout<<"SHIT! What is this crap Im doing?\n";
while (!codefin.eof())
{
getline(codefin,texline);
cout<<"Read :"<<texline<<endl;
latex_out.push_back(texline);
}
codefin.close();
latex_out.push_back("\\end{KODcpp}");
}
}

}
fin.close();

ofstream fout(argv[1]);
if (!fout.is_open())
{
cout<<"Could not open the file "<<argv[1]<<endl<<endl;
return -1;
}
cout<<" Writing "<<argv[1]<<endl;
for (unsigned int i=0;i<latex_out.size();i++)
fout<<latex_out[i]<<endl;
fout.close();
return 0;
}

-------------------------------------------------------------------------
The input file is a latex file that contains

\begin{KODcpp}
.... INSERT c++ code HERE...
\end{KODcpp}

at different places, not nested.

Jan 21 '06 #3

P: n/a
Gunnar G wrote:
I am not sure. Post _real_ code, *complete* and *compilable*.


Here it is then.
int main(){

[redacted]
vector<string> source;
vector<string> latex_out; // the resulting latex file
string codefile;
ofstream codefout;
ifstream codefin;
ifstream fin(argv[1]);
if (!fin.is_open())
{
cout<<"Could not open the file "<<argv[1]<<endl<<endl;
return -1;
}
cout<<" Opening "<<argv[1]<<endl;
while (!fin.eof())
{
getline(fin,line);
[loop body redacted]
}
fin.close();

[remainder of function redacted]
}


Your loop is incorrect. Please see FAQ 15.5
(http://www.parashift.com/c++-faq-lit...html#faq-15.5).

fin.eof() only returns true *AFTER* an attempt to read past EOF. So you
will attempt to read an extra line. Your while loop should read:

while (getline(fin,line))
{
// body of loop.
}

This will exit on EOF.
Jan 21 '06 #4

P: n/a
> Your loop is incorrect. Please see FAQ 15.5
(http://www.parashift.com/c++-faq-lit...html#faq-15.5).

Thanks, I'll look right away,

But the problem seems to be that eof() is still true after closing the file
and opening it again.
So open() just openes the file, nothing else.

A call to clear() solved things.
Jan 21 '06 #5

P: n/a
On Sat, 21 Jan 2006 21:13:05 GMT in comp.lang.c++, Gunnar G
<de****@comhem.se> wrote,
But the problem seems to be that eof() is still true after closing the file
and opening it again.


After an operation fails, whether because of eof or some other
reason, the stream is in a failed state and will do nothing more for
you until you .clear() it.

Jan 21 '06 #6

P: n/a
David Harmon wrote:
On Sat, 21 Jan 2006 21:13:05 GMT in comp.lang.c++, Gunnar G
<de****@comhem.se> wrote,
But the problem seems to be that eof() is still true after closing the file
and opening it again.


After an operation fails, whether because of eof or some other
reason, the stream is in a failed state and will do nothing more for
you until you .clear() it.


Yes, but I believe that this is a deficiency in the standard. .close()
followed by .open() should clear any previous state.
Jan 22 '06 #7

P: n/a

"red floyd" <no*****@here.dude> wrote in message
news:%e*******************@newssvr29.news.prodigy. net...
David Harmon wrote:
On Sat, 21 Jan 2006 21:13:05 GMT in comp.lang.c++, Gunnar G
<de****@comhem.se> wrote,
But the problem seems to be that eof() is still true after closing the
file
and opening it again.


After an operation fails, whether because of eof or some other
reason, the stream is in a failed state and will do nothing more for
you until you .clear() it.


Yes, but I believe that this is a deficiency in the standard. .close()
followed by .open() should clear any previous state.


If a stream is in a 'fail' state, I don't believe
'close()' will succeed.

-Mike
Jan 22 '06 #8

P: n/a
Mike Wahler wrote:
"red floyd" <no*****@here.dude> wrote in message

Yes, but I believe that this is a deficiency in the standard. .close()
followed by .open() should clear any previous state.


If a stream is in a 'fail' state, I don't believe
'close()' will succeed.

-Mike


EOF is a fail state. Why should it fail to close when you've reached EOF?
Jan 22 '06 #9

P: n/a

"red floyd" <no*****@here.dude> wrote in message
news:AE*******************@newssvr13.news.prodigy. com...
Mike Wahler wrote:
"red floyd" <no*****@here.dude> wrote in message
Yes, but I believe that this is a deficiency in the standard. .close()
followed by .open() should clear any previous state.
If a stream is in a 'fail' state, I don't believe
'close()' will succeed.

-Mike


EOF is a fail state.


Right.
Why should it fail to close when you've reached EOF?


Because, as I understand it, once 'good()' returns 'false',
any other operation on the stream will fail, including
'close()'.

There might be exceptions of which I'm unaware, but my
experience has been that when 'eof()' returns 'true',
so will 'fail()' (this makes sense to me because triggering
'eof()' results from an attempt to read past eof, which
would mean the read operation failed, setting 'failbit'.

-Mike
Jan 22 '06 #10

P: n/a

Mike Wahler wrote in message ...

"red floyd" <no*****@here.dude> wrote in message
news:AE*******************@newssvr13.news.prodigy .com...
Mike Wahler wrote:
"red floyd" <no*****@here.dude> wrote in message
Yes, but I believe that this is a deficiency in the standard. .close()
followed by .open() should clear any previous state.

If a stream is in a 'fail' state, I don't believe
'close()' will succeed.
-Mike


EOF is a fail state.


Right.
Why should it fail to close when you've reached EOF?


Because, as I understand it, once 'good()' returns 'false',
any other operation on the stream will fail, including
'close()'.

There might be exceptions of which I'm unaware, but my
experience has been that when 'eof()' returns 'true',
so will 'fail()' (this makes sense to me because triggering
'eof()' results from an attempt to read past eof, which
would mean the read operation failed, setting 'failbit'.

-Mike


Got me curious, so I added to a test-section I had going:

// #includes
int main(){
using std::cout;
std::ifstream Ping("Bob4.png", std::ios_base::binary );
if( !Ping ){
cout<<"\n ifstream Ping(\"Bob4.png\", binary) FAILED"
<<std::endl;
}
cout<<" ofstream Ping.tellg() = "
<<Ping.tellg()<<std::endl;
Ping.seekg(0, std::ios::end);
cout<<" Ping.seekg(0, ios::end) Ping.tellg() = "
<<Ping.tellg()<<std::endl;
Ping.seekg(0, std::ios::beg);
cout<<" Ping.seekg(0, ios::beg) Ping.tellg() = "
<<Ping.tellg()<<std::endl;
std::vector<unsigned char> Image;
char In(0);
while( Ping.get(In) ){
Image.push_back(static_cast<unsigned char>(In));
}
cout<<"\n Image.size() = "<<Image.size()
<<" bytes."<<std::endl;
for(size_t i(0); i < 100; ++i){
int out( static_cast<int>( Image.at(i) ) );
cout<<std::setw(3)<<out<<" ";
if((i>0)&&(i%10) == 0){ cout<<std::endl;}
}
cout<<std::endl;
cout<<" ifstream Ping.tellg() = "<<Ping.tellg()<<std::endl;

Ping.close();
Ping.open("Bob4.xpm", std::ios_base::binary );
if( !Ping ){
cout<<"\n ifstream Ping(\"Bob4.xpm\", binary) FAILED"
<<std::endl;
}
cout<<" Ping.good() = "<<Ping.good()<<std::endl;
Ping.seekg(0, std::ios::end);
cout<<" Ping.seekg(0, ios::end) Ping.tellg() = "
<<Ping.tellg()<<std::endl;
Ping.clear();
Ping.seekg(0, std::ios::end);
cout<<" Ping.clear(); Ping.seekg(0, ios::end) Ping.tellg() = "
<<Ping.tellg()<<std::endl;
cout<<" Ping.good() = "<<Ping.good()<<std::endl;
Ping.seekg(0, std::ios::beg);
cout<<" Ping.seekg(0, ios::beg) Ping.tellg() = "
<<Ping.tellg()<<std::endl;
Ping.get(In);
unsigned char Unum(static_cast<unsigned char>(In));
int out( static_cast<int>( Unum ) );
cout<<std::setw(3)<<out<<" ";
cout<<std::endl;
return 0;
} // main() end

// -- output --
// ofstream Ping.tellg() = 0
// Ping.seekg(0, ios::end) Ping.tellg() = 4499
// Ping.seekg(0, ios::beg) Ping.tellg() = 0
// Image.size() = 4499 bytes.
// 137 // [snip]
// ifstream Ping.tellg() = -1
// ifstream Ping("Bob4.xpm", binary) FAILED
// Ping.good() = 0
// Ping.seekg(0, ios::end) Ping.tellg() = -1
// Ping.clear(); Ping.seekg(0, ios::end) Ping.tellg() = 25597
// Ping.good() = 1
// Ping.seekg(0, ios::beg) Ping.tellg() = 0
// 47

Note how the stream was in a fail-state after EOF, but, I was able to
..close() {which also puts the stream in a fail-state (according to my old
docs)} and then open the next file (still in a fail-state), then .clear() the
stream and use it to access the 2nd file(something you normally would not
do.<G>).

Comments? Is it UB that just seems to work?

[ This test was on a P4, win98, GCC 3.3.1(MinGW) machine. ]
[ fail-state == std::ios::fail set on stream object. ]
--
Bob R
POVrookie
Jan 23 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.