473,395 Members | 1,622 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,395 software developers and data experts.

EOF problem

I have a function that is suppose to read a list of records from a text file into a linked list. But if the file doesn't exist it is suppose to create one. I tried a while (!file.eof()) but it still seems to run through the loop once even if is an already existing or newly created empty file. By running through the loop it is filling my linked list with garbage values and results in later crashing when trying to access the linked list.

Expand|Select|Wrap|Line Numbers
  1. void read_file(acnt *rec_temp, int &total_rec)
  2. {
  3.     fstream file;
  4.     char string[100];
  5.     acnt *head = rec_temp;
  6.  
  7.     file.open("banks.txt", ios::in | ios::app);                            //open file
  8.  
  9.     if(!file)                                                            // if file could not be opened
  10.     {
  11.     cerr << "Error: File could not be opened!" << endl;
  12.     exit(1);
  13.     }
  14.  
  15.  
  16.     if (!file.eof())                                                    //if file is not empty
  17.     {
  18.         while (!file.eof())                                                //read until end of file
  19.         {
  20.             file >> rec_temp->number;
  21.  
  22.             file >> string;
  23.             rec_temp->fname = new name;
  24.             rec_temp->fname->new_name(string);
  25.  
  26.             file >> string;
  27.             rec_temp->lname = new name;
  28.             rec_temp->lname->new_name(string);
  29.  
  30.             file >> rec_temp->balance;
  31.  
  32.             rec_temp->next = new acnt;
  33.             rec_temp->next->prev = rec_temp;
  34.             rec_temp = rec_temp->next;
  35.  
  36.             total_rec++;
  37.         }
  38.  
  39.         file.close();
  40.  
  41.         rec_temp->prev->next = NULL;
  42.         delete rec_temp;
  43.         head->prev = NULL;
  44.     }
  45.     else                                                                //File is empty, set list to NULL
  46.     {
  47.         rec_temp = NULL;
  48.         rec_temp->number = NULL;
  49.         rec_temp->fname = NULL;
  50.         rec_temp->lname = NULL;
  51.         rec_temp->balance = NULL;
  52.         rec_temp->next = NULL;
  53.         rec_temp->prev = NULL;
  54.     }
  55. }
  56.  
Feb 18 '07 #1
11 1713
AdrianH
1,251 Expert 1GB
I have a function that is suppose to read a list of records from a text file into a linked list. But if the file doesn't exist it is suppose to create one. I tried a while (!file.eof()) but it still seems to run through the loop once even if is an already existing or newly created empty file. By running through the loop it is filling my linked list with garbage values and results in later crashing when trying to access the linked list.

Expand|Select|Wrap|Line Numbers
  1. void read_file(acnt *rec_temp, int &total_rec)
  2. {
  3.     fstream file;
  4.     char string[100];
  5.     acnt *head = rec_temp;
  6.  
  7.     file.open("banks.txt", ios::in | ios::app);                            //open file
  8.  
  9.     if(!file)                                                            // if file could not be opened
  10.     {
  11.     cerr << "Error: File could not be opened!" << endl;
  12.     exit(1);
  13.     }
  14.  
  15.  
  16.     if (!file.eof())                                                    //if file is not empty
  17.     {
  18.         while (!file.eof())                                                //read until end of file
  19.         {
  20.             file >> rec_temp->number;
  21.  
  22.             file >> string;
  23.             rec_temp->fname = new name;
  24.             rec_temp->fname->new_name(string);
  25.  
  26.             file >> string;
  27.             rec_temp->lname = new name;
  28.             rec_temp->lname->new_name(string);
  29.  
  30.             file >> rec_temp->balance;
  31.  
  32.             rec_temp->next = new acnt;
  33.             rec_temp->next->prev = rec_temp;
  34.             rec_temp = rec_temp->next;
  35.  
  36.             total_rec++;
  37.         }
  38.  
  39.         file.close();
  40.  
  41.         rec_temp->prev->next = NULL;
  42.         delete rec_temp;
  43.         head->prev = NULL;
  44.     }
  45.     else                                                                //File is empty, set list to NULL
  46.     {
  47.         rec_temp = NULL;
  48.         rec_temp->number = NULL;
  49.         rec_temp->fname = NULL;
  50.         rec_temp->lname = NULL;
  51.         rec_temp->balance = NULL;
  52.         rec_temp->next = NULL;
  53.         rec_temp->prev = NULL;
  54.     }
  55. }
  56.  
Sorry, there is not enough here to compile.

However, one pointer I have is that you make your class acnt do the filling of the class/struct acnt.

A class should do operations on itself for itself. This is because it knows itself best and it localises the code affecting acnt objects in one location. This allows you transfer or to do those operations elsewhere in your system without having to copy code.

To allow for doing an operation like this:
Expand|Select|Wrap|Line Numbers
  1. cin >> *rec_temp;
add the following member to you acnt class(or struct as they are almost equivilant)
Expand|Select|Wrap|Line Numbers
  1. class acnt
  2. {
  3. ...
  4. public:
  5.   std::istream& operator>>(std::istream& lhs) // lhs = left hand side of operator
  6.   {
  7.     // Fill this object with data such as:
  8.     lhs >> number;  // replaces file >> rec_temp->number
  9.  
  10.     return lhs;
  11.   }
  12. ...
  13. };
  14.  
Hope this helps,


Adrian
Feb 18 '07 #2
RRick
463 Expert 256MB
I can not get this code to create a non-existent file with ios::in and ios:app open modes. I'm using gnu 3.4.5. The following link (http://rafb.net/efnet_cpp/tutorials/..._openmode.html) says that gnu is using the correct behavior. You should be able to create a new file only with trunc. I really don't know which compiler is right.

There is another option you can try: ios::ate. This sets the pointer to the end of the file at creation. This might work with your system. I suspect that eof is not set on creation of the file with ios:app because ios::app is meant to be used with writing, not reading. You might need to do a read before eof is set. Maybe the ios::ate open will fix this.

Why are you opening a data file with read/write permissions? Generally, data files are read only and opening them with write permission is a bug waiting to happen.
Feb 18 '07 #3
AdrianH:

It's been a while since I did c++ programming and I couldn't remember how to do overloaded operators. This is just a homework assignment (one where I have already gone way beyond what was required) but if I get this problem figured out, I will might try to go back and clean up the code some (like what you suggested). I will also post the code in it's entirety so you can compile it.

RRick:

I will try some of the different methods you suggested. I'm not worries about the security of the program (like I said this is just a homework assignment), but the reason for having ios::in and ios:app is because I didn't know how else to create a file if it didn't exist.



Here's the code for the entire program:
***Code moved to next post becuase it was too long***


It seems to work fine if a file already exist and has at least one account stored in it. But with no stored data the program crashes. If you want to make a file to test it with, just call it "banks.txt" and put one record in it like this:

500 Mary Jane 789.79

Make sure there is no newline after "789.79"
Feb 18 '07 #4
AdrianH
1,251 Expert 1GB
It seems to work fine if a file already exist and has at least one account stored in it. But with no stored data the program crashes.
Sorry for deleting your code, but posting the entire thing is a bad idea due to copiers (bad students) on the forums.

However, your last statement tells me what you are doing wrong:
Expand|Select|Wrap|Line Numbers
  1.     }
  2.     else                                                                //File is empty, set list to NULL
  3.     {
  4.         rec_temp = NULL;
  5.         rec_temp->number = NULL;
  6.         rec_temp->fname = NULL;
  7.         rec_temp->lname = NULL;
  8.         rec_temp->balance = NULL;
  9.         rec_temp->next = NULL;
  10.         rec_temp->prev = NULL;
  11.     }
  12.  
If you notice, you are setting rec_temp to NULL. Just after it you then set everything in it to NULL. Now if you point at something, you can set anything in it to whatever you like. But if you point at nothing, is there anything in it to set?

Tell me if you get what I am saying.


Adrian
Feb 19 '07 #5
AdrianH:

Yeah that makes sense. So I should just set rec_temp to NULL (I thought about that but wasn't sure when I wrote it). But actually that whole if statement (and the else) was added after the fact that I was having problems with my loop, to try and fix my problem.
For some reason, it will always never execute the else statement (the part where everything was set to NULL). my code had this statement written in it:

Expand|Select|Wrap|Line Numbers
  1. if (! file.eof)
  2. {
  3.         while(! file.eof)
  4.         {
  5.         .....
  6.         }
  7. }
  8. else
  9. {        
  10.         rec_temp = NULL;
  11.         .....
  12. }
  13.  
I will always

Regardless of the fact that file may be empty or had just been created (and therefore empty), it always executes the if and while loop....never the else. and if it is an empty file it runs the while loop only once. Why doesn't the "! file.eof" statement work?


P.S.
No worries about deleting the code, I understand.
Feb 19 '07 #6
AdrianH
1,251 Expert 1GB
AdrianH:

Yeah that makes sense. So I should just set rec_temp to NULL (I thought about that but wasn't sure when I wrote it). But actually that whole if statement (and the else) was added after the fact that I was having problems with my loop, to try and fix my problem.
For some reason, it will always never execute the else statement (the part where everything was set to NULL). my code had this statement written in it:

Expand|Select|Wrap|Line Numbers
  1. if (! file.eof)
  2. {
  3.         while(! file.eof)
  4.         {
  5.         .....
  6.         }
  7. }
  8. else
  9. {        
  10.         rec_temp = NULL;
  11.         .....
  12. }
  13.  
I will always

Regardless of the fact that file may be empty or had just been created (and therefore empty), it always executes the if and while loop....never the else. and if it is an empty file it runs the while loop only once. Why doesn't the "! file.eof" statement work?


P.S.
No worries about deleting the code, I understand.
Oh, I see. The reason why the ! file.eof statement doesn't work... mmmm, no wait, your code within the if and within the loop should never execute. The reason is that the eof member is not a member variable but a member function. Your statement is getting the pointer to the function. An ! in front of it should make it 0. I don't know why your code is executing the way it is, but try putting an empty set of parenthesis after the eof. This will then execute the member function and not get its address.

Try that and let me know the results. If it works like I think it should, you can remove the exterior if around the while loop as the while loop will not execute when it reaches the end of the file.


Adrian
Feb 19 '07 #7
Oops, when i typed that last bit of code I forgot the "()" after the eof. But it actually is there is there in my code. So, no that still doesn't work for some reason.
Feb 19 '07 #8
AdrianH
1,251 Expert 1GB
Oh, sorry, didn’t reread your first post. Ignore my last one. The problem is not the eof. You are using that correctly

I wrote a small programme to test this eof problem. Here it is:
Expand|Select|Wrap|Line Numbers
  1. #include <fstream>
  2. #include <iostream>
  3.  
  4. using namespace std;
  5. int main()
  6. {
  7.     fstream file;
  8.     file.open("banks.txt", ios::in | ios::app);
  9.     if (!file) {
  10.         cout << "File not opened" << endl;
  11.         exit(1);
  12.     }
  13.     while (!file.eof()) {
  14.         cout << "reading line: '";
  15.         char buffer[2000];
  16.         file.getline(buffer, 2000);
  17.         cout << buffer << "'" << endl;
  18.     }
  19. }
  20.  
I found that if the file exists, ios::app will cause it not to open. Probably because ios:app is an output flag, and you are opening an input stream. If you get rid of ios::app, it opens the file if it is there.

Now as to why the !file.eof() doesn’t work... well, actually it does. You just haven’t reached the end of the file since you haven’t read from it yet. Try using file.peek() prior to the loop. This will cause the file to be read and if there is nothing in it, it will set the eof bit.

Hope this helps.


Adrian
Feb 19 '07 #9
DeMan
1,806 1GB
Hi,

I'm not entirely sure whether this applies here, but occasionally you see strange behaviour of eof in different languages because some check eof as "The next read will fail because there is nothing left" and others read it as "the previous read failed because there were no characters". Not being 100% familiar with the eof() method I can't be sure this is the problem, but I suspect you may need to attempt at least one read before you call file.eof().
Feb 19 '07 #10
AdrianH
1,251 Expert 1GB
Hi,

I'm not entirely sure whether this applies here, but occasionally you see strange behaviour of eof in different languages because some check eof as "The next read will fail because there is nothing left" and others read it as "the previous read failed because there were no characters". Not being 100% familiar with the eof() method I can't be sure this is the problem, but I suspect you may need to attempt at least one read before you call file.eof().
You are correct. Hence the need to call peek().


Adrian
Feb 19 '07 #11
DeMan
1,806 1GB
I have a habit of typing slowly, so I actually submitted before I saw your post (oops!!)
Feb 19 '07 #12

Sign in to post your reply or Sign up for a free account.

Similar topics

11
by: Kostatus | last post by:
I have a virtual function in a base class, which is then overwritten by a function of the same name in a publically derived class. When I call the function using a pointer to the derived class...
117
by: Peter Olcott | last post by:
www.halting-problem.com
18
by: Ian Stanley | last post by:
Hi, Continuing my strcat segmentation fault posting- I have a problem which occurs when appending two sting literals using strcat. I have tried to fix it by writing my own function that does the...
28
by: Jon Davis | last post by:
If I have a class with a virtual method, and a child class that overrides the virtual method, and then I create an instance of the child class AS A base class... BaseClass bc = new ChildClass();...
6
by: Ammar | last post by:
Dear All, I'm facing a small problem. I have a portal web site, that contains articles, for each article, the end user can send a comment about the article. The problem is: I the comment length...
16
by: Dany | last post by:
Our web service was working fine until we installed .net Framework 1.1 service pack 1. Uninstalling SP1 is not an option because our largest customer says service packs marked as "critical" by...
2
by: Mike Collins | last post by:
I cannot get the correct drop down list value from a drop down I have on my web form. I get the initial value that was loaded in the list. It was asked by someone else what the autopostback was...
0
by: =?Utf-8?B?am8uZWw=?= | last post by:
Hello All, I am developing an Input Methop (IM) for PocketPC / Windows Mobile (PPC/WM). On some devices the IM will not start. The IM appears in the IM-List but when it is selected from the...
1
by: sherifbk | last post by:
Problem description ============== - I have 4 clients and 1 server (SQL server) - 3 clients are Monitoring console 1 client is operation console - Monitoring console collects some data from...
9
by: AceKnocks | last post by:
I am working on a framework design problem in which I have to design a C++ based framework capable of solving three puzzles for now but actually it should work with a general puzzle of any kind and I...
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: 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: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.