| | |
Reading data into files
Please support our C++ advertiser: Intel Parallel Studio Home
![]() |
•
•
Join Date: Jan 2005
Posts: 5
Reputation:
Solved Threads: 0
I'm currently writing a program and I want it to read in data from a source and if needed change some or all of it and re-write it to the same source file.
I have:
where all the variables are ints in a struct called date.
ifstream ifs("data.txt");
ifs>>date.hours;
ifs>>date.minutes;
ifs>>date.month;
ifs>>date.day;
ifs>>date.year;
and to output I have:
ofstream ofs("data.txt");
ofs<<date.hours;
ofs<<date.minutes;
ofs<<date.month;
ofs<<date.day;
ofs<<date.year;
Right now I read all of the data into the strut and do what ever operations I need and then read it all back. The problem is in larger text files I still need to read it all into my program, and then read it all back out. Is there a way to read in only one entry say minutes, and change it and then write it back as the new value WITHOUT having to read and write the rest of the text file entries. So I can just change the one entry?
I have:
where all the variables are ints in a struct called date.
ifstream ifs("data.txt");
ifs>>date.hours;
ifs>>date.minutes;
ifs>>date.month;
ifs>>date.day;
ifs>>date.year;
and to output I have:
ofstream ofs("data.txt");
ofs<<date.hours;
ofs<<date.minutes;
ofs<<date.month;
ofs<<date.day;
ofs<<date.year;
Right now I read all of the data into the strut and do what ever operations I need and then read it all back. The problem is in larger text files I still need to read it all into my program, and then read it all back out. Is there a way to read in only one entry say minutes, and change it and then write it back as the new value WITHOUT having to read and write the rest of the text file entries. So I can just change the one entry?
•
•
Join Date: Jan 2005
Posts: 5
Reputation:
Solved Threads: 0
The format looks something like this:
21 10 3 13 2005
for each entry which corresponds to the form: hour-minute-month-day-year
The first number in the file is the number of entries in the file. So a file with 3 sets of date looks like this:
3
21 10 3 13 2005
12 8 4 9 2004
3 6 10 31 2004
If there is an easier way to make this file i'm open to suggestions.
21 10 3 13 2005
for each entry which corresponds to the form: hour-minute-month-day-year
The first number in the file is the number of entries in the file. So a file with 3 sets of date looks like this:
3
21 10 3 13 2005
12 8 4 9 2004
3 6 10 31 2004
If there is an easier way to make this file i'm open to suggestions.
Consider the following pseudocode for modifying a record:
A good C++ reference should should give you the details.
C++ Syntax (Toggle Plain Text)
while ( !in.eof() ) { pos = in.tellg(); rec = read_rec ( in ); if ( rec == search_rec ) { modify_field ( rec, new_entry ); in.seekg ( pos ); write_rec ( rec ); } }
I'm here to prove you wrong.
>only works as long as you know precisely how many char's it is until the entry u want to write?
Nope, with your format you only need to know how many fields are in the record before the one you want to modify. Since each record is on a separate line, in.tellg() saves the location at the beginning of each record so that you can return to the beginning of the line and rewrite the record. Here's a sample execution with the file you gave:
Say you want to change 12 8 4 9 2004 to 12 8 4 11 2004. in.tellg() saves the position just before 21. You read the record, then test it to see if it's the one you want. The test fails, so the loop continues to the next iteration. in.tellg() saves the position just before 12 and the record is read. The test succeeds because this is the record you want to change, so modify_record is called to change 9 to 11. How it does so is irrelevant to the loop. With the modified record in hand, in.seekp ( pos ) resets the file pointer to the beginning of the line so that the new record can be rewritten over the old record.
Nope, with your format you only need to know how many fields are in the record before the one you want to modify. Since each record is on a separate line, in.tellg() saves the location at the beginning of each record so that you can return to the beginning of the line and rewrite the record. Here's a sample execution with the file you gave:
C++ Syntax (Toggle Plain Text)
21 10 3 13 2005 12 8 4 9 2004 3 6 10 31 2004
I'm here to prove you wrong.
•
•
•
•
Originally Posted by Narue
Say you want to change 12 8 4 9 2004 to 12 8 4 11 2004C++ Syntax (Toggle Plain Text)
21 10 3 13 2005 12 8 4 9 2004 3 6 10 31 2004
ie
21 10 03 13 2005
12 08 04 09 2004
03 06 10 31 2004
That makes each record a fixed length and maybe a little easier to code.
Ignore everything I said, I've been working with record-oriented files too much. Let's try again, this time when I'm actually thinking about the problem at hand instead of making it up as I go along.
>Is there a way to read in only one entry say minutes, and change it and
>then write it back as the new value WITHOUT having to read and write the
>rest of the text file entries.
With byte-oriented files, no, not really. There isn't a convenient and efficient way to shift bytes, so you're looking at the same issue as if you wanted to insert new data into an array. Technically, you only need to rewrite everything after and including the modified record, and a rewrite of the latter part of the file is only necessary if the new record differs in byte size from the old record. Even then, you can pad with empty space if the new record is smaller.
It would probably be better in your case to work with each line on a case by case basis, using a temporary file as your output. That way you only have to keep one record in fast memory at a time, and the temporary file can simply be renamed to replace the old file. No more copying is necessary at that point, but you still have to read and write the entire contents of the file once.
>Is there a way to read in only one entry say minutes, and change it and
>then write it back as the new value WITHOUT having to read and write the
>rest of the text file entries.
With byte-oriented files, no, not really. There isn't a convenient and efficient way to shift bytes, so you're looking at the same issue as if you wanted to insert new data into an array. Technically, you only need to rewrite everything after and including the modified record, and a rewrite of the latter part of the file is only necessary if the new record differs in byte size from the old record. Even then, you can pad with empty space if the new record is smaller.
It would probably be better in your case to work with each line on a case by case basis, using a temporary file as your output. That way you only have to keep one record in fast memory at a time, and the temporary file can simply be renamed to replace the old file. No more copying is necessary at that point, but you still have to read and write the entire contents of the file once.
I'm here to prove you wrong.
![]() |
Similar Threads
- Creating MP3 data CDs (OS X)
- reading from text files and manipulating the data....how (Visual Basic 4 / 5 / 6)
- Writing mp3 files to data files (OS X)
Other Threads in the C++ Forum
- Previous Thread: C++ Reorder random numbers
- Next Thread: exponents in c++
| Thread Tools | Search this Thread |
api array based beginner binary bitmap c++ c/c++ calculator char char* class code coding compile compiler console conversion count database delete deploy desktop developer dll download dynamic dynamiccharacterarray email encryption error file forms fstream function functions game givemetehcodez google graph gui homeworkhelp homeworkhelper iamthwee ifstream input int integer java lib linkedlist linker list loop looping loops map math memory multiple news node number numbertoword output parameter pointer problem program programming project python random read recursion recursive reference rpg sorting string strings struct temperature template test text text-file tree unix url variable vector video visualstudio win32 windows winsock word wordfrequency wxwidgets






