I am very experienced in file operations (because i cant use 3rd party stuff, i end up having to write it all myself).
First lesson in file ops: There is a STRICT algorithm. I have written functions specifically to fill this algorithm.
To check whether a file is there or not, we will have to open it. Here's the basic algorithm for checking whether a file exists:
1. open it for INput
2. is it open? if yes, close the file and return true; if no, return false
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
/** both file_there() and data_there()
return false if the file/data is not there.
*/
bool file_there(string file)
{
ifstream in;
in.open(file.c_str(), ios::in);
if(!in.is_open())
{
return false;
}
if(in.is_open())
{
in.close();
return true;
}
return false;
}
|
***********************************************************
we return false, because if it isn't open, but it still exists (in other words, it isn't not open), then... well.... we can't do anything. Chances are that condition is impossible to meet, though, because a file either exists, or does not exist. The return is just for stability.
Notice that instead of
in.open("file.dat", ios::in)
, we use
in.open(file.c_str(), ios::in);
. This is optional. You can open a file using a string, instead of a string-constant by appening to the end of any string name
.c_str()
. This makes it so that i can call this function with any file name, and it will do all the work. I dont have to write the algorithm every time i want to check for file existence.
************************************************************
now we have checked it. But, lets say there file is there. What if the file is empty? There will be nothing to work with.
We will check to see if there is any data in the file. You may wonder why we do this separately. Here is why: A file can exist, and contain data. It could also exist and contain data. Because this returns false if 1: the file isnt there and 2: if there is no data there; we want to write this separately. If the file_there() function returns true, but this returns false, the file exists, but does not contain any data. Here is the algorithm:
1. open file for input (check if it exists too)
2. get each line in the file (because it is there)
3. count the number of lines which are greater than nothing
4. if the number of lines which are greater than nothing, is greater than 0, there is data, return true; if the number of lines which is greater than nothing is equal to 0, then there is no data in the file, return false.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
bool data_there(string file)
{
string line;
int number_of_lines = 0;
ifstream in;
in.open(file.c_str(), ios::in);
if(in.is_open())
{
number_of_lines = 0;
while(!in.eof())
{
getline(in, line);
if(line > "")
{
number_of_lines++;
}
}
in.close();
}
if(number_of_lines > 0)
{
return true;
}
if(number_of_lines <= 0)
{
return false;
}
return false;
}
|
Now, all we have done is checked for data, and file existence. Now that we have, we will use an algorithm, to extract the data structure. Keep in mind that what you are doing is a bit complex (i dont want to say its advanced, because it really isn't, not at all). I recommend you study and try to grasp the concepts I'm about to give you.
First, we will set our data structure. Right now im working on a program which has a data structure of 5 pieces (5 pieces of information in a static order; static meaning it will never change). if we want to keep that data structure, but have 1 piece if data which is out of line (lets say we want to password protect our program, and the password is the first line in the file, then the rest is the data structure). Here is the steps we would take to get that piece of data, and return that piece of data (the piece of data, whether it has been modified, changed, etc...) to the file, without de-stabalizing the rest of the file.
1. get the entire file into a vector
2. vector[0] = our data
3. over-write the file with out vector
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
ifstream in;
ofstream out;
vector<string> file;
string line, first_line;
in.open("data.dat", ios::in);
while(!in.eof())
{
getline(in, line);
file.push_back(line);
}
in.close();
file[0] = first_line;
cout<< "Tell me what the first line will be!"<< endl;
getline(cin, first_line);
cin.sync();
file[0] = first_line;
out.open("data.dat", ios::out);
for(unsigned int x = 0; x < file.size(); x++)
{
out<< file[x]<< endl;
}
out.close();
return 0;
|
what this does is get the whole file, put each line into a vector, and overwrite the whole file with the vector. Here is where our data goes: from file, to vector; -- use/modify data in vector--; from vector, to file.
since only 1 'slot' in the vector has changed, only 1 line in the file will.