C++ file handling q

I’m having a hell of a time with a problem and I can’t seem to figure out how to make it work.

I’m building a database program to let users insert, remove, edit and display products. Products are written a .txt file for retrieval just prior to display.

My problem is, every time I read out, I always get one more entry then I read in and I can’t seem to figure out how to make it stop doing it.
OUTPUT:

I made it this farI made it this farI made it this far
Name: name
Catagory: catagory
Description: description
Store: stores
Related: related
Price: 1.00

Name: name2
Catagory: cat2
Description: description2
Store: stores2
Related: related2
Price: 2.00

Name:
Catagory:
Description:
Store:
Related:
Price: 2.00

void list::read()
{

//declare variables
char tempname[50];
char tempcatagory[15];
char tempdescription[100];
char tempstore[50];
char temprelated[100];
float tempprice;
pnum = 0;

//wipe before read in
for (int i=0; i<noofprod; ++i)
{
plist*.name[0] = ‘\0’;
plist*.catagory[0] = ‘\0’;
plist*.description[0] = ‘\0’;
plist*.store[0] = ‘\0’;
plist*.related[0] = ‘\0’;
plist*.price = 0.0;
}

//open the file
in.open(“product.txt”);

//checks for file presence
//If the file doesn’t exist, dump back to the menu
if(!in)
cout<<“There are no products. Please enter some!”<<endl;
//If the file does exist, continue
else
if(in)
{
//begin read in loop
do
{

            //read in name
            in.get(tempname, 50, '

');
in.clear();
in.get();

            //copy to record
            strcpy(plist[pnum].name, tempname);

            //read in catagory
            in.get(tempcatagory, 15, '

');
in.clear();
in.get();

            //copy to record
            strcpy(plist[pnum].catagory, tempcatagory);

            //read in description
            in.get(tempdescription, 100, '

');
in.clear();
in.get();

            //copy to record
            strcpy(plist[pnum].description, tempdescription);

            //read in store
            in.get(tempstore, 50, '

');
in.clear();
in.get();

            //copy to record
            strcpy(plist[pnum].store, tempstore);

            //read in related
            in.get(temprelated, 100, '

');
in.clear();
in.get();

            //copy to record
            strcpy(plist[pnum].related, temprelated);

            //read in price
            in&gt;&gt;tempprice;
            in.clear();
            in.get();

            //copy to record
            plist[pnum].price = tempprice;

            //increment counter
            ++pnum;

            //error checking to make sure the loops are recorded
            cerr&lt;&lt;"I made it this far";
    //end read-in loop
    }
    while(!in.eof());

//end if
}

//close the file
in.close();

//end function
}

//Function to display products by name
void list::display_order()const
{

//Begin display loop
for(int i=0; i<pnum; ++i)
{
//Display members
cout<<"
Name: "<<plist*.name<<endl;
cout<<"Catagory: "<<plist*.catagory<<endl;
cout<<"Description: "<<plist*.description<<endl;
cout<<"Store: "<<plist*.store<<endl;
cout<<"Related: "<<plist*.related<<endl;
cout<<"Price: "<<plist*.price<<endl;

//End the display loop
}

//End the display function
}

PRODUCT.TXT(my file)

name
catagory
description
stores
related
1
name2
cat2
description2
stores2
related2
2

If your output is running 1 more time than your input, then intuitively I would think you should try running your output loop one less time:

for(int i=0; i<(pnum-1); ++i)

instead of

for(int i=0; i<pnum; ++i)

Your read in loop does not count pnum==0 as an entry; the first entry is actually when pnum==1. Your display loop, however, is counting pnum==0 as something to display. You could condition the for loop as
for (;pnum>0;pnum–)
to achieve what you want. Though I didn’t test the code.