Reputation: 397
I'm trying to read and write a sequence of int pairs from a file. The file would look something like this:
0 6
12 24
48 33
23 24
80 79
My goal is to read each pair into a struct:
struct foo {
int a;
int b;
}
And then push each struct into a stack. However, fstreams have proven rather difficult to handle for this task. Right now, my file read code looks like this:
std::fstream fileStream(file, std::ios::in);
int a, b;
while (fileStream >> a >> b) {
myStack.push({ a, b });
}
And my input might look like this (I have to do it individually because of what I'm using it for...):
inputFoo(foo bar) {
std::fstream fileStream(file, std::ios::out);
fileStream << bar.a << " " << bar.b;
}
However, I have a feeling this isn't how I should be efficiently and safely doing this. I also have a function that checks if the file exists already, but I'm not sure that one works either:
bool fileExists() {
std::ifstream stream;
return stream.good();
}
What's the best way to actually do this?
Upvotes: 3
Views: 3516
Reputation: 19607
You don't need fileExists()
function. The stream in that function was not even open. Just check like this:
std::fstream fileStream(file, std::ios::in);
if(!fileStream.is_open())
{
// handle the error
}
Now, if you'd like, there are few suggestions that don't change the logic:
std::ifstream
for input and you can omit the std::ios::in
argumentstd::ofstream
for output and you can omit the std::ios::out
argumentoverload <<
and >>
operators of foo
:
struct foo
{
int a;
int b;
foo() : a(0), b(0) {} // default constructor to make it a little more c++ and less c
friend std::istream &operator>>(std::istream &is, foo &f);
std::ostream &operator<<(std::ostream &os)
{
return os << a << " " << b;
}
};
// Both can be friend, only operator<< can be member
std::istream &operator>>(std::istream &is, foo &f)
{
return is >> f.a >> f.b;
}
to which you can pass not only file streams, but for example std::cin
and std::cout
(might be useful for debugging and console input-output). You'll read like this:
foo f;
while(fileStream >> f)
myStack.push(f);
And write even simpler:
fileStream << bar;
As to your comment, this is the only thing that comes to my mind:
const std::string filePath = "file.txt";
std::ifstream ifs(filePath);
if(ifs.is_open())
{
// read
}
else
{
std::ofstream ofs(filePath);
// write
}
Upvotes: 3
Reputation: 61
do like this
std::ifstream fileStream(file, std::ios::in);
while (!fileStream.eof()) {
foo f;
fileStream >> f.a>> f.b
myStack.push(f);
}
loop will end of reading the entire file
Writing will be like this
std::ofstream fileStream(file, std::ios::in);
while (!myStack.isEmpty()) {
foo f;
f=myStack.pop();
fileStream << f.a<<" "<< f.b<<endl;
}
Upvotes: 4