![]() |
|
#1
|
|||
|
|||
Random access filesI am having some problems trying to get my file to read a random access file correctly. It mixes it up and does not give the right outputs for the lines. Could someone please point me in the right direction.
CPP / C++ / C Code:
Code:
Last edited by LuciWiz : 06-May-2006 at 02:49.
Reason: Please insert your C code between [c] & [/c] tags
|
|
#2
|
||||
|
||||
Re: Random access filesQuote:
#2: Never use feof() to decide when to end a read loop. Here's why #3: Also read Guideline #1 __________________
Age is unimportant -- except in cheese |
|
#3
|
|||
|
|||
Re: Random access filesQuote:
It's kind of hard to see why things are bad just by looking at the output (It turns out that, in fact, the behavior is undefined, and different people with different compilers and operating systems might see different symptoms.) So, instead of working from the output, let's look at the significant parts of the program: You have declared a struct with 320 chars. How can you know that? Two ways: 1. Analysis: The struct has a total of eight arrays of char and each array has 40 char. 2. Make the program tell you: Put printf("sizeof emp = %d\n", sizeof(emp)); in your program. Now, what does the following do? CPP / C++ / C Code:
1. It reads 320 bytes from the file. If there are fewer than 320 bytes then it reads everything that is in the file, but for now, let's say it reads 320 bytes. (See Footnote.) 2. It stores those chars into the 320-byte memory block dedicated to emp. Note that whatever was in those memory locations is overwritten by the stuff from the file each time through the loop. What does this do? CPP / C++ / C Code:
1.It goes to the address of emp.id (which is the address of the first byte in the struct). 2. It starts pulling bytes from successive memory locations and putting them to stdout. It does this until a byte with value zero is encountered. It doesn't put the zero byte to stdout. 3. It puts a '\n' character to stdout and then a space char. 4. It goes to the address of emp.sun (which is 40 bytes greater than the address of the first byte in the struct). 5. It starts pulling bytes from successive memory locations and putting them to stdout. It does this until a byte with value zero is encountered. It doesn't put the zero byte to stdout. 6. It puts a '\n' character to stdout and then a space char. 7. It continues in a like manner for all of the other %s parameters. I hope that you have seen enough to make you realize what the problem(s) is(are). Regards, Dave Footnote: For any program that uses fread, I recommend that you check the returned value from fread to make sure it reads the number of bytes that you ask for. Maybe something like: CPP / C++ / C Code:
If you do this, you will find that, as Walt said, feof() is not very useful as a loop exit condition. |
|
#4
|
|||
|
|||
Re: Random access filesOk, sorry for the noob post. Dave thanks for telling me what my code is doing. I am writting it straight from a book, on how it tells me to "Read Data from a Random-Access File"
this is the example of how it tells me to read a Random-Access File; CPP / C++ / C Code:
When I make the file credit.dat for it to read from it also has problems reading from it, so I guess its not a very good example for me to be using for my program. The book only has four pages on this topic and im not allowed to use C++ in my project. I have been successful at reading data from a Sequential-Access File so im thinking of changing my project2input.dat to that. But if I can find a way to read the text from a random access file I would rather do that just to say I did it. Well im at a loss still, so im off to borders to scavenge through there books to see if i can get a clue as to what im doing. Thanks |
|
#5
|
|||
|
|||
Re: Random access filesQuote:
If you are going to use fread() to read the (binary) bytes from a file directly into a struct, the file must have been created in a way that this can be done. Creating a file with a text editor won't make it work. (That is to say that I don't have a text editor that will allow me (easily) to create a line of text with exactly 10 chars including a zero byte and no newline or 15 chars including a zero char and no newline, which is what this code expects to read for the name fields. I can't easily create the binary bytes of an int (and no newline), which is what this program requires --- let alone the big-endian/little-endian issues that you get into with binary numbers in files.) The only practical way that I see to use the code that you posted is to write a program that creates the file with whatever data you want to use. The program would fill in the struct(s) with whatever values you want to use, and then use fwrite to write the struct(s) to a binary file. Furthermore, the loop is formed improperly, as Walt and I have mentioned. If your file is perfect, and contains a number of bytes that is exactly an integer multiple of the size of the struct, the program will always go through the loop an extra time, since the eof flag is not set until the program attempts to read bytes after the end of the file. This is a typical beginner error, and if books have examples like this, I can see how people get the wrong ideas. (And, if your file is not perfect --- that is, it doesn't contain a number of bytes that is an exact multiple of the size of the struct, the program will be operating on incorrect data for the extra bytes, since there is no checking to see if fread was successful in obtaining the requested number of bytes). All in all, a bad example. (But that's just my opinion.) But before you get to the "small" detail of getting out of the loop, you have to either create a proper binary data file, or change the program so that it doesn't read binary data directly into the entire struct. If you aren't actually required to use binary data files, and if you want to use a file created by a text editor, then you might consider changing the program so that it reads the individual struct members with whatever method you are already familiar with. (fgets followed by sscanf would be one possibility that may be worth considering.) Regards, Dave |
|
#6
|
|||
|
|||
Re: Random access filesok I guess my biggest question is how should I format my text to write a program so it reads it. My teacher gave us a doc and sayed do what you want with it. He took over the semester and gave us no clue on what to do with this doc. Told us to figgure it out.
these are the rules that he gave us, Rules: 1. All employees MUST work on one weekend day (Either saturday or sunday, NOT BOTH) 2. Employees cannot work more than 6 hrs on any given day 3. Shifts can be assigned only in odd numbered hours (eg: 7am - 11 am. You cannot do 7 am - 10 pm or 8 am - 10 am, or 8 am - 3 pm or 1 pm - 4 pm or any other even numbered hour) 4. Work 14 hrs on weekdays and 6 hrs on weekends ( First Preference) - Can be split into 4 hrs a day for 2 weekdays and 6 hrs a day on one weekend day ( 4*2 + 6 + 6) - You can have an employee work 2 hours in the morning and 2/4 hours at another time in the day 5. Work 16 hrs on weekdays and 4 hrs on weekends ( Second Preference) - Can be split into 4 hrs a day for 4 weekdays and 4 hrs a day on one weekend day ( 4*4 + 4)/or - Can be split into 6 hrs a day for 2 weekdays and 4 hrs a day for 1 weekday and 4 hrs a day on one weekend day (6*2 + 4 *1 + 4) - You can have an employee work 2 hours in the morning and 2/4 hours at another time in the day But before I can do any of that I need to figgure out how to make this document so that I can get all the data to read into my program. I did start to type out a sequential doc but then I came to days that they can work at two different times and that messed me up. Now im totaly confused on how to do this. here is 6 of the 40 employees schedules for an example Code:
|
|
#7
|
|||
|
|||
Re: Random access filesQuote:
That's a good start: you gotta read the data. Your first effort defined a struct to hold employee data and declared an array of eight such structs. The problem was that you were trying to use fread(), and you discovered that the file that you created with a text editor simply wouldn't work with that approach. Period. End of approach number 1. Now, let's keep the data file. Let's keep the struct, and for now, the array of structs just the way you had them (so your program won't handle more than eight employees without changing something, but that's ok for now). For each employee, there are eight lines in the data file. To get information about an employee into his struct, use getline() to read a line at a time into a buffer (a string). Your struct has an int for the Employee ID. That int has to be on the first line. So, after the line is into a buffer, your program has to find the int on that line. How? That is up to you. Anyhow, find the int and store its value in the employee ID member of that struct. The successive lines have the form "Dayofweek: xxxx" Where Dayofweek is Sunday, Monday, ... and "xxxx" is either the exact text "Cannot Work" or a range of hours like "7 am - 1 pm". You have made struct elements that are arrays of chars for the "xxxx" data for each day of the week, and you can store the "xxxx" information there, exactly as it appears in the input file, if you want to. Sooner or later, you will have to parse the information to classify the employee's time according to the schedule requirements. Maybe you will decide to put some other information in the struct (instead of or in addition to the "xxxx" read in from the file), but for now, let's just see if you can read in and store all information that you need from the input file and print out everything that you have stored. Make sure that you read exactly everything in the file and that there is no superfluous stuff in your array. Make sure that the employee count that you obtained from reading the individual records is exactly correct. It's not too early to think about what to do in case if input file errors (what if there are more than eight employees in the file? what if one of them is missing one of the days of the week? what if...) Since it's your program and you are creating the data base, you can make any rules that you want. For example: each employee must have exactly eight line entries as you have shown. Another example of an input rule: Blank lines between employees can be made mandatory to make it easier to check the data base with a text editor, or could be optional (maybe multiple blank lines between records are OK but no blank lines in a given record), etc., etc. My point is that you have given an example of the data base you intend to use. I think you should write down all of the details so that someone else could create a database for your program. It's called a Program Specificaiton, and usually I would expect an instructor to give its requirements to you. In this case I guess you get to make up your own program specification. I strongly recommend that you write it down. This will be useful to you as a reference as you implement (and debug) the code, and in real applications it becomes the most important single piece of documentation outside of the source code itself. Regards, Dave |
Recent GIDBlog
Toyota - 2008 September Promotion by Nihal
| Thread Tools | Search this Thread |
| Rate This Thread | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| access remote files in an application | kris82 | Apache Web Server Forum | 1 | 06-Feb-2006 15:00 |
| Bloodshed Dev C++ Project Options | JdS | C++ Forum | 6 | 11-Nov-2005 17:23 |
| random number generation issues | Jonnyz007 | C++ Forum | 8 | 27-Oct-2005 19:13 |
| Apache2 config issues | monev | Apache Web Server Forum | 2 | 28-Jun-2004 06:19 |
| Can't view pages from another machine on the Intranet | aevans | Apache Web Server Forum | 9 | 14-May-2004 02:26 |
Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The