473,387 Members | 1,455 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Help with simple file reading issue please

Hi,

Thanks in advance for the help. I have been to many websites and tried
several solutions to my problem, but have fixed part of it. It's time to
come humbly to the newsgroups for help :-)

By the way, please don't reply just to tell me that my code isn't optimized
and that I should use a delimited database rather than a line by line
record. If I had my way, I'd do it differently too.

I am reading in a file that looks like this..
<snip>

Jul 22 '05 #1
7 1872
Thanks in advance for the help. I have been to many websites and tried
several solutions to my problem, but have fixed part of it. It's time to
come humbly to the newsgroups for help :-)

By the way, please don't reply just to tell me that my code isn't optimized and that I should use a delimited database rather than a line by line
record. If I had my way, I'd do it differently too.

I am reading in a file that looks like this..
<snip>

Crap, let's try that again..

uh, looks like this..

item2
type
dude
ds**@dsfds.com
4.44
avail

With code that looks like this...

Multi is an ifstream

Multi.open("Multimedia.txt");
if (!Multi){}
else{
while (!Multi.eof()){
m = new Multimedia();
string Item;
getline(Multi, Item, '\n');
m->setName(Item);
string Type;
getline(Multi, Type, '\n');
m->setType(Type);
string By;
getline(Multi, By, '\n');
m->setAuthor(By);
string Owner;
getline(Multi, Owner, '\n');
m->setOwner(Owner);
float Price;
Multi >> Price;
Multi.ignore(100,'\n');
m->setPrice(Price);
string Availability;
getline(Multi, Availability, '\n');
m->setStatus(Availability);

MM.push_back(*m); //linked list (STL)
}
}
Multi.close();

It was worse until I added the Multi.ignore line, but I still have a
problem.
My result is two records instead of one. Obviously I am pulling the price
information out twice (left in buffer?) and it is obvious that it has to do
with the fact that I am using cin to get it. I can't use getline for
getting a float, so I need to find a way to clear the buffer out.

Am I even on the right track? Can someone help me please?

Shane

Jul 22 '05 #2
"Shane" <NO**************@zaft.com> wrote in message
news:Ja********************@comcast.com...
Thanks in advance for the help. I have been to many websites and tried
several solutions to my problem, but have fixed part of it. It's time to come humbly to the newsgroups for help :-)

By the way, please don't reply just to tell me that my code isn't optimized
and that I should use a delimited database rather than a line by line
record. If I had my way, I'd do it differently too.

I am reading in a file that looks like this..
<snip>

Crap, let's try that again..

uh, looks like this..

item2
type
dude
ds**@dsfds.com
4.44
avail

With code that looks like this...

Multi is an ifstream

Multi.open("Multimedia.txt");
if (!Multi){}
else{
while (!Multi.eof()){
m = new Multimedia();
string Item;
getline(Multi, Item, '\n');
m->setName(Item);
string Type;
getline(Multi, Type, '\n');
m->setType(Type);
string By;
getline(Multi, By, '\n');
m->setAuthor(By);
string Owner;
getline(Multi, Owner, '\n');
m->setOwner(Owner);
float Price;
Multi >> Price;
Multi.ignore(100,'\n');
m->setPrice(Price);
string Availability;
getline(Multi, Availability, '\n');
m->setStatus(Availability);

MM.push_back(*m); //linked list (STL)
}
}
Multi.close();

It was worse until I added the Multi.ignore line, but I still have a
problem.
My result is two records instead of one. Obviously I am pulling the price
information out twice (left in buffer?) and it is obvious that it has to

do with the fact that I am using cin to get it. I can't use getline for
getting a float, so I need to find a way to clear the buffer out.

Am I even on the right track? Can someone help me please?


That looks like the old "improper use of eof" problem. See the FAQ
(http://www.parashift.com/c++-faq-lite/), section 15 ("Input/output via
<iostream> and <cstdio>"), question 5 ("Why does my input seem to process
past the end of file?").

By the way, the dynamic allocation of the Multimedia object (m = new
Multimedia();) looks like it is unnecessary and possibly causing a memory
leak. Did you mean to write "Multimedia m;"?

--
David Hilsee
Jul 22 '05 #3

"David Hilsee" <da*************@yahoo.com> wrote in message
news:rd********************@comcast.com...
"Shane" <NO**************@zaft.com> wrote in message
news:Ja********************@comcast.com...

<snip>
That looks like the old "improper use of eof" problem. See the FAQ
(http://www.parashift.com/c++-faq-lite/), section 15 ("Input/output via
<iostream> and <cstdio>"), question 5 ("Why does my input seem to process
past the end of file?").

By the way, the dynamic allocation of the Multimedia object (m = new
Multimedia();) looks like it is unnecessary and possibly causing a memory
leak. Did you mean to write "Multimedia m;"?

--
David Hilsee


I looked at that exact article before, but ignored it because it skips the
whole purpose of using getline for everything else. In other words, if my
record looks like this:

Item name with spaces
Record
Full Name with spaces
ds**@dsfds.com
4.44
Available on request with spaces

then I have issues. So I tried your suggestion, but I lose the first cin in
the record to the x variable. This throws the whole record off. If I use
getline, I can grab everything in the line and pull it into the variable of
my choice. Am I missing something?

Thanks again for the help!
Shane
Jul 22 '05 #4
"Shane" <NO**************@zaft.com> wrote in message
news:6_********************@comcast.com...

"David Hilsee" <da*************@yahoo.com> wrote in message
news:rd********************@comcast.com...
"Shane" <NO**************@zaft.com> wrote in message
news:Ja********************@comcast.com...

<snip>
That looks like the old "improper use of eof" problem. See the FAQ
(http://www.parashift.com/c++-faq-lite/), section 15 ("Input/output via
<iostream> and <cstdio>"), question 5 ("Why does my input seem to
process past the end of file?").

By the way, the dynamic allocation of the Multimedia object (m = new
Multimedia();) looks like it is unnecessary and possibly causing a memory leak. Did you mean to write "Multimedia m;"?

--
David Hilsee


I looked at that exact article before, but ignored it because it skips the
whole purpose of using getline for everything else. In other words, if my
record looks like this:

Item name with spaces
Record
Full Name with spaces
ds**@dsfds.com
4.44
Available on request with spaces

then I have issues. So I tried your suggestion, but I lose the first cin

in the record to the x variable. This throws the whole record off. If I use
getline, I can grab everything in the line and pull it into the variable of my choice. Am I missing something?

Thanks again for the help!


Yes, the example uses operator>>, but the idea can be applied to many other
circumstances as well. The problem is the same: eof() is being set after
you attempt to read past the end of the file. The first iteration does not
attempt to read _past_ the end of the file, so the loop continues on for
another iteration, adding a second object to the linked list. You do not
check to see if any of the input operations succeed, so the second iteration
silently fails to retrieve input from the file after the first iteration
read all of the input.

Now, suppose there were a function std::istream& operator>>(std::istream&,
Multimedia&) that would allow you to read a Multimedia from a stream. Then
you could write your loop as

Multimedia m;
while( Multi >> m ) {
MM.push_back(m);
}

if ( !Multi.eof() ) {
// Something bad happened. Should have attempted to read past
// the end of the file to end the loop.
}

The above would silently ignore a partial Multimedia entry, but you could
fix that, if you like. The other option would be to add error handling to
your code. For example,

getline(Multi, Item, '\n');

should be changed so you know if the read was successful, like so

if ( !getline(Multi, Item, '\n') ) {
std::cerr << "Error reading Item" << std::endl;
break;
}

You'll need to add similar error handling for the other input operations you
perform. Your code will now complain loudly when it fails to read from the
file. However, that would still render your call to eof() useless, because
the loop will most likely end once an error has occurred, not when eof()
returns true. Give those changes a shot and see if it helps you understand
what's going on.

--
David Hilsee
Jul 22 '05 #5
On Sun, 22 Aug 2004 19:16:31 -0700, "Shane"
<NO**************@zaft.com> wrote in comp.lang.c++:

"David Hilsee" <da*************@yahoo.com> wrote in message
news:rd********************@comcast.com...
"Shane" <NO**************@zaft.com> wrote in message
news:Ja********************@comcast.com...


<snip>
That looks like the old "improper use of eof" problem. See the FAQ
(http://www.parashift.com/c++-faq-lite/), section 15 ("Input/output via
<iostream> and <cstdio>"), question 5 ("Why does my input seem to process
past the end of file?").

By the way, the dynamic allocation of the Multimedia object (m = new
Multimedia();) looks like it is unnecessary and possibly causing a memory
leak. Did you mean to write "Multimedia m;"?

--
David Hilsee


I looked at that exact article before, but ignored it because it skips the
whole purpose of using getline for everything else. In other words, if my
record looks like this:

Item name with spaces
Record
Full Name with spaces
ds**@dsfds.com
4.44
Available on request with spaces

then I have issues. So I tried your suggestion, but I lose the first cin in
the record to the x variable. This throws the whole record off. If I use
getline, I can grab everything in the line and pull it into the variable of
my choice. Am I missing something?

Thanks again for the help!
Shane


Yes, you are missing the fact that in C++ and C, from which C++
inherits the behavior, end of file does not work the way you think.
Not for C style <stdio.h> streams nor for C++ stream objects.

The end of file indicator is NEVER set for a stream because you just
read the last item from the stream and the NEXT read will fail. The
end of file indicator is only set for a stream AFTER you try to read
PAST THE END of the file.

You are checking for end of file before you do the read. If there is
one item in a file and you have read that one item, the end of file
indicator will be false. When you try to read the second item, there
is nothing left in the file and the read fails, sets the end of file
indicator, and leaves the destination untouched. So it still contains
whatever was previously in it, perhaps the first record.

You need to do the check for end of file either after reading, or
while reading the data.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 22 '05 #6
In article <Ja********************@comcast.com>,
"Shane" <NO**************@zaft.com> wrote:
Thanks in advance for the help. I have been to many websites and tried
several solutions to my problem, but have fixed part of it. It's time to
come humbly to the newsgroups for help :-)

By the way, please don't reply just to tell me that my code isn't

optimized
and that I should use a delimited database rather than a line by line
record. If I had my way, I'd do it differently too.

I am reading in a file that looks like this..
<snip>

Crap, let's try that again..

uh, looks like this..

item2
type
dude
ds**@dsfds.com
4.44
avail

With code that looks like this...

Multi is an ifstream

Multi.open("Multimedia.txt");
if (!Multi){}
else{
while (!Multi.eof()){
m = new Multimedia();
string Item;
getline(Multi, Item, '\n');
m->setName(Item);
string Type;
getline(Multi, Type, '\n');
m->setType(Type);
string By;
getline(Multi, By, '\n');
m->setAuthor(By);
string Owner;
getline(Multi, Owner, '\n');
m->setOwner(Owner);
float Price;
Multi >> Price;
Multi.ignore(100,'\n');
m->setPrice(Price);
string Availability;
getline(Multi, Availability, '\n');
m->setStatus(Availability);

MM.push_back(*m); //linked list (STL)
}
}
Multi.close();

It was worse until I added the Multi.ignore line, but I still have a
problem.
My result is two records instead of one. Obviously I am pulling the price
information out twice (left in buffer?) and it is obvious that it has to do
with the fact that I am using cin to get it. I can't use getline for
getting a float, so I need to find a way to clear the buffer out.

Am I even on the right track? Can someone help me please?


Try this:

istream& operator>>( istream& s, Multimedia& m )
{
string item;
getline( s, item );
m.setName( item );
getline( s, item );
m.setType( item );
// etc...
return s;
}

Then in your code:

Multimedia m;
while ( Multi >> m )
MM.push_back( m );
Jul 22 '05 #7
>
Yes, the example uses operator>>, but the idea can be applied to many other circumstances as well. The problem is the same: eof() is being set after
you attempt to read past the end of the file. The first iteration does not attempt to read _past_ the end of the file, so the loop continues on for
another iteration, adding a second object to the linked list. You do not
check to see if any of the input operations succeed, so the second iteration silently fails to retrieve input from the file after the first iteration
read all of the input.

Now, suppose there were a function std::istream& operator>>(std::istream&,
Multimedia&) that would allow you to read a Multimedia from a stream. Then you could write your loop as

Multimedia m;
while( Multi >> m ) {
MM.push_back(m);
}

if ( !Multi.eof() ) {
// Something bad happened. Should have attempted to read past
// the end of the file to end the loop.
}

The above would silently ignore a partial Multimedia entry, but you could
fix that, if you like. The other option would be to add error handling to
your code. For example,

getline(Multi, Item, '\n');

should be changed so you know if the read was successful, like so

if ( !getline(Multi, Item, '\n') ) {
std::cerr << "Error reading Item" << std::endl;
break;
}

You'll need to add similar error handling for the other input operations you perform. Your code will now complain loudly when it fails to read from the file. However, that would still render your call to eof() useless, because the loop will most likely end once an error has occurred, not when eof()
returns true. Give those changes a shot and see if it helps you understand what's going on.

--
David Hilsee


Thanks for all the suggestions. It's working properly now :-)

Shane
Jul 22 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Dave Mateer | last post by:
Hi Why does the following code allow me to keep the same session when in the same sub domain (ie admin.localhost), yet not when I goto another related domain eg main.localhost? I would like...
2
by: \Dandy\ Randy | last post by:
Hello everyone. I have been following misc posts, as well as reading several FAQ's on this issue, unfortunatley I cannot locate a solution. I am hoping that someone will be able to provide me with...
6
by: KevinD | last post by:
assumption: I am new to C and old to COBOL I have been reading a lot (self teaching) but something is not sinking in with respect to reading a simple file - one record at a time. Using C, I am...
0
by: gunimpi | last post by:
http://www.vbforums.com/showthread.php?p=2745431#post2745431 ******************************************************** VB6 OR VBA & Webbrowser DOM Tiny $50 Mini Project Programmer help wanted...
4
by: Brad Isaacs | last post by:
I am working with ASP.NET 2.0 and using an SQL Server 2000 database. I am using Visual Studio 2005 and developing on my Local machine. I am working with Login controls ASP.Configuration, I...
12
by: adamurbas | last post by:
ya so im pretty much a newb to this whole python thing... its pretty cool but i just started today and im already having trouble. i started to use a tutorial that i found somewhere and i followed...
0
by: Sells, Fred | last post by:
I'm running python 2.5 (or 2.4) in an XP environment. I downloaded and installed the .dll's from OpenLDAP-2.4.8+OpenSSL-0.9.8g-Win32.zip and copied the .dll's in c:/windows/system32 as instructed...
2
by: =?Utf-8?B?U2NvdHRSYWREZXY=?= | last post by:
I'm creating a doc project for my c# program. I've done this before but this time sonething is wrong. I build my doc project and is succeeds but when I open the help file, there is no documentation...
2
by: vijaykumardahiya | last post by:
Hello Sir, I have a simple Issue but It is not resolve by me i.e input parameter are not store in Ms-Access. I store the input parameter through Standard Action <jsp:useBean>. jsp:useBean call a...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.