File access question
Hi. Two quick queries:
1) Can a file be opened for ascii input and output at the same time? If so, would this be two separate instances or one instance with a different flag?
2) Can a specific line or element of a file be removed in situ?
The end result I am seeking is to go through a file containing a bunch of numbers, find the first instance of a specific number, and remove it, without having to see the rest of the numbers. Currently my model is to open it for input, selectivly copy all the elements to a vector, then open it for output and load the contents of the array back. Problem is, this involves having to pull the entire length of the file, even after I know where what I am looking for is. Is there any way to just go to it, clear it in situ, and then be done?
fstream inout ("file.txt", ios::in, ios::out)
Something like that should work. Not sure if the syntax is correct.
You help me so i shall help you too, ironic...hmm
Q 1) yes you can have both open at the same time (input and output) and yes they both require instances, however you cannot have any more files open at the same time....
Q 2) if you want direct access don't use the vector....
here's a little outline that should give you a good idea on what to use depending on your specifications...
hope this helps
Given ten Standard C++ Library containers, which type of container is best suited for solving a particular problem? Sometimes the answer is obvious, but other times there can be several viable alternatives. For the difficult cases, you may want to compare the actual execution timings using different containers to determine the best alternative. For most other cases, these simple criteria can help you decide:
How are values going to be accessed?
If random access is important, then a vector or a deque should be used. If sequential access is sufficient, then one of the other structures may be suitable.
Is the order in which values are maintained in the collection important?
There are a number of different ways values can be sequenced. If a strict ordering is important throughout the life of the container, then the set data structure is an obvious choice, as insertions into a set are automatically placed in order. If this ordering is important only at one point?for example, at the end of a long series of insertions?then it might be easier to place the values into a list or vector, and sort the resulting structure at the appropriate time. If the order that values are held in the structure is related to the order of insertion, then a stack, queue, or list may be the best choice.
Will the size of the structure vary widely over the course of execution?
If so, a list or set might be the best choice. A vector or deque will continue to maintain a large buffer even after elements have been removed from the collection. Conversely, if the size of the collection remains relatively fixed, than a vector or deque will use less memory than a list or set holding the same number of elements.
Is it possible to estimate the size of the collection?
The vector data structure provides a way to pre-allocate a block of memory of a given size, using the reserve() member function. This ability is not provided by the other containers.
Is testing to see whether a value is contained in the collection a frequent operation?
If so, then the set or map containers would be a good choice. Testing to see whether a value is contained in a set or map can be performed in a very small number of steps, logarithmic in the size of the container, whereas testing to see if a value is contained in one of the other types of collections might require comparing the value against every element being stored by the container.
Is the collection indexed?
That is, can the collection be viewed as a series of key/value pairs? If the keys are integers between 0 and some upper limit, a vector or deque should be used. On the other hand, if the key values are some other ordered datatype?character, string, or user-defined type?the map container can be used.
Can values be related to each other?
All values stored in any container provided by the Standard C++ Library must be able to test for equality against another similar value, but not all need to recognize the relational less-than operator. However, if values cannot be ordered using the relational less-than operator, they cannot be stored in a set or a map.
Is finding and removing the largest value from the collection a frequent operation?
If the answer is yes, the priority queue is the best data structure to use.
At what positions are values inserted into or removed from the structure?
If values are inserted into or removed from the middle, then a list is the best choice. If values are inserted only at the beginning, a deque or a list is the preferred choice. If values are inserted or removed only at the end, a stack or queue may be a logical choice.
Is the merging of two or more sequences into one a frequent operation?
If so, a set or a list would seem to be the best choice, depending whether the collection is maintained in order. Merging two sets is a very efficient operation. If the collections are not ordered, but the efficient splice() member function from class list can be used, then the list datatype is to be preferred, since this operation is not provided in the other containers.
While I seem to have gotten good answers to the first question, I think you misunderstood the second. I don't WANT to read the data into any kind of container. I would prefer to just:
read a single unit of data
determine if it is equal to a constant
if it is, delete it in situ and then close the file
if not, move on to the next data
The problem is, how do I delete a single element from a file that is open for reading.
what I do now is:
read a unit of data
determine if it is equal to a constant
if it is not, add it to the back of a vector, then move on to the next data (queue would prolly be better, but neither is what I want)
if it is, skip it, and add the rest of the file's elements to the vector
close the file, delete the entire file, and output the contents of the vector back into the now empty file.
This is horribly inefficient in that I am required to read data elements AFTER my target is isolated. So the question boils back down to deleting an element in situ. I want to avoid storing the file's contents in my program, I would prefer to make modifications directly to the file. Is this possible?
>I would prefer to make modifications directly to the file.
This is possible, but in binary mode it is tedious even for well formatted files and in text mode is incredibly difficult since the file positioning operations are highly restricted with text files. If the file is strictly formatted, meaning both lines and columns, in such a way that you can overwrite the data you want to without worry of overwriting anything else then you can do it that way and end up with a blank space in your file which can be sorted out later.
Otherwise the easiest way is to use a data structure to hold the file such as a binary tree (if no two records are equal) where you can search efficiently and write everything back to the file except what you want to delete.
Well would it be possible for, say a space delimited set of numbers? I belive the file's get buffer's pointer would be pointed in roughly the right direction, could I just put spaces to that offset?
The thing is, I am only going after the FIRST instance of a number, but most of the program's execution time is iterating through the rest of the file, loading and unloading data that I would rather just leave be.