Hello highwayman,
Like
Enoizat when I loaded your code I had several errors and even after some of the original errors I received some new errors.
Some things I have found that have not been mentioned yet.
In "main" I had to add the header file "<string>". Given the line
std::cout << "Hello World!\n";
on the rhs of "<<" is a string and the header file is needed so that "cout" and "<<" will know how to process this string. "<iostream>" is not enough to make this line work.
In the header file and the ".cpp" file for "SaveStream" everything works until you get to the template part. I do not know a lot about templates, but I have learned that when you define a template in a header file the function that goes with the prototype needs to be in the same file. What I did was to copy and comment out the function in the ".cpp" file and paste it into the header file. Once all the template information was in the same file it compiled fine.
I am still not sure why all the template information needs to be in the same file, but I accept that this is the way it is done and it works.
In the "SaveStrea.cpp" file the first two functions are OK there.
Tn the "SaveStream::SaveStream: function what I see there is:
The code
saveFile.open(saveTo);
"saveFile" was defined as a fstream, so when you open the file you have to tell it if you are opening the stream for input, output or both. Also you are using "read" and "write" which work on binary files to read chunks of the file which means you would also have to open the file in "binary" mode. But since you are creatint a a text file you should not open the file in "binary" mode.
In the code:
1 2 3 4 5 6
|
if (!saveFile.is_open())
{ // if the file doesn’t exist
std::ofstream temp;
temp.open(saveTo); // make it as a new file
saveFile.open(saveTo); // and then open the new file
}
|
As
Enoizat has showed you in his code the if statement can be simply written as
if (!saveFile)
. It works just as well and works slightly better as a more generic form with out all the extra work of calling the function.
When you create "temp" as an "ofstream" it implies that you are opening the file for output and as you are using it will create the file if it does not exist. It may also be a good idea to close "temp" after you have created the file because you no longer need it.
In the open statement again you need to tell it how you want to open the fstream, input, output or both. "fstream" is not designed to default to any stream type and it can not read your mind to know what you want.
Over time I have found it to be a good practice that when opening a stream for input to check an make sure the stream is open. Nor quite as necessary for an output stream because if the file does not exist it will create it before writing to the file. If the output stream has a path to the file then it becomes more of a necessity to check if it is open because as I have found something wrong in the path to the file could cause the file stream not to open.
In the "SaveStream::exists" function the line
while (!saveFile.eof())
does not work the way you are thinking. The way your code is written by the time the while condition determines that it has reached "eof" you have entered the while loop more more time than is needed.
To use the while condition as you have it this would work better:
1 2 3 4 5 6 7 8 9 10 11 12
|
saveFile >> currVar;
while (!saveFile.eof())
{
if (currVar == (varName + ":"))
{
does_exist = true;
break;
}
saveFile >> currVar;
}
|
By doing the first read before the while condition and then doing all the other reads at the end of the while loop
!saveFile.eof()
will work as it should and the while loop will end when it should. The other , more often used, method is:
1 2 3 4 5 6 7 8
|
while (saveFile >> currVar;)
{
if (currVar == (varName + ":"))
{
does_exist = true;
break;
}
}
|
This way when the read sets "eof" the condition and the loop fail. This tends to be the best way to read a file of any size without knowing what is in the file.
If you are writing this to a file
var1Name: 534172;
var2Name: hdbdtwy74#$a);
var3Name: 1;
var4Name: 348.227;
|
you will need to account for the
var1Name:
part when reading the file.
I.E.,
while (saveFile >> junk >> currVar;)
. Where "junk" reads the heading and stops at the ":". This is a general idea because the input you are using has int, double and string as the variable.
The first thing you have to decide on is if you are going to work with the file as a text file or a binary file. It will make a difference how you read and write to the file. Be aware that the above example is for using a text file.
In the template function in the else part you have
while ()
. This does not mean that it is to be an endless loop, but does produce an error because there needs to be something in the () for the condition to check. At this I am not sure what to put for the condition to get the loop to end.
I am thinking that the while loop could be replaced with
saveFile.seekg(0, saveFile.end
. In the past when I have used "seekp" to position the output file pointer it did not work as I expected, but "seekg" did work on both input and output when "fstream" was used as the stream type/
For now these are things I see and questions that need an answer before the program can be corrected to work the way that you want.
Also when you put headings in a file you need to account for them when reading the file however you open the file.
Hope that helps,
Andy