check extensions
Why does ifstream successfully open a directory?
Sometimes I want infile.open(whatever) to fail if it's fed a non-existent file name. But if I pass it something like "home/icecube/" it opens successfully even though it didn't open a file. So then it tries infile>>inum or something and my program crashes.
I guess I can make sure that that function is never called unless it's given valid file.
Or maybe within the function I can check to see if the extension is correct in addition to checking if the file opened correctly? I know I only I only want to open .ani files.
I guess I could do something like this:
temp=anifile[anifile.length()-4];
temp+=anifile[anifile.length()-3];
temp+=anifile[anifile.length()-2];
temp+=anifile[anifile.length()-1];
infile.open(anifile.c_str());
if(temp==".ani"&&infile.fail()==false)
{
//do stuff
}
But that's sort of crazy.
I'm changing a lot of stuff, in the near future this won't matter because I won't be sending the function bad filenames. But still this seems like something I should know the answer to.
#include <fstream>#include <iostream>int main(){ std::ifstream foo("blah.txt"); // That file does not exist. std::cout << "open: " << foo.is_open() << std::endl;}
That prints open: 0 for me, proving that the file was in fact, no open.
If you were to try and perform read operations on it, only then would foo.fail() become true.
Actually I tried that right before you posted. It doesn't work for me. My problem isn't sending it a file that does not exist. My problem is if I sent it a DIRECTORY that does exist. Below if anifile=="Data/Anibox/" which is a directory then infile.is_open==true!
I want to keep from entering the if statement if a directory is passed.
I want to keep from entering the if statement if a directory is passed.
infile.open(anifile.c_str()); if(infile.is_open()) { Death(); name=anifile; infile>>itype; infile>>isize; infile>>iloop; ipics=new GLuint[isize]; for(ix=0;ix<isize;ix++) { infile>>temp; temp="Data/Images/"+temp; picbox->ImageLoader(temp,ipics[ix]); } }
Quote:Original post by icecubeflower
Below if anifile=="Data/Anibox/" which is a directory then infile.is_open==true
#include <iostream>#include <fstream>int main(){ std::cout << std::ifstream("somedir").is_open() << std::endl;}
That does not happen for me with VS8 (though it would with gcc under *NIX, as a directory is a file, as is almost anything else).
What compiler are you using?
Quote:I want to keep from entering the if statement if a directory is passed.
C++ I/O knows nothing about directories. You will either need to use platform-specific APIs to detect whether you are dealing with a file or with a directory.
For C++, portable results, I suggest using Boost's file I/O utilities.
Oh yeah, that "everything is a file on unix" thing. Yeah I'm using g++ on Linux. I'm also compiling it on windows, though.
I don't want to include boost. Eventually I won't be sending the function directories so it won't matter. It just sort of bugged me that is_open() wouldn't fail. I guess I'll just check for a .ani extension for now.
I don't want to include boost. Eventually I won't be sending the function directories so it won't matter. It just sort of bugged me that is_open() wouldn't fail. I guess I'll just check for a .ani extension for now.
Quote:Original post by icecubeflower
Oh yeah, that "everything is a file on unix" thing. Yeah I'm using g++ on Linux. I'm also compiling it on windows, though.
Create a /linux and a /win32 directories in which you stick OS-specific implementations of utility functions. Then write two implementations of a is_directory() function, using stat() on Linux, and GetFileAttributes() on Win32.
Then, depending on your platform, you compile one directory or another. No, I'm not a big fan of mixing multiple-platform code in a single file through conditional compilation.
Quote:I don't want to include boost.
*shrug*
Quote:Eventually I won't be sending the function directories so it won't matter.
That kind of reasoning is how security holes happen.
Quote:It just sort of bugged me that is_open() wouldn't fail.
Note that read operations will still fail if you open a directory.
Quote:I guess I'll just check for a .ani extension for now.
Just keep in mind that a directory can too end in ".ani". ;)
Quote:Quote:
Eventually I won't be sending the function directories so it won't matter.
That kind of reasoning is how security holes happen.
Does it really matter? I mean suppose someone does send the function a .ani file but the format is all wrong. Suppose I'm expecting int, int, int, string, string, string, in the file. But they give me some file with garbage in it. That will still crash my program. I mean if I go in the directories of any of the store-bought professional games I have and replace their data files with files with the same name but filled with random characters then those programs crash too. I mean if we're not checking the the file format is perfect then why would checking that a directory is not passed be any more important?
If you are serious about becoming a professional software developer then yes, it does matter quite a bit. Ensuring your program behaves in a controlled manner when fed bad data is very important.
I would be very much surprised if those commercial games you mentioned really crashed when fed bad data, the way it happens when the operating system kills your process for an access violation, for example, rather than logging an error (cannot open file, bad data format, bad checksum, etc) and cleanly shutting down.
Here and now, for your specific program, it may not matter, but that is not code you can be proud of.
I would be very much surprised if those commercial games you mentioned really crashed when fed bad data, the way it happens when the operating system kills your process for an access violation, for example, rather than logging an error (cannot open file, bad data format, bad checksum, etc) and cleanly shutting down.
Here and now, for your specific program, it may not matter, but that is not code you can be proud of.
Well. Do you have any links for me to read or something? I don't know how to make sure that the .ani file my function receives is formatted correctly. I mean if I'm expecting int isize, int, int and then isize strings but instead the file contains three random numbers followed by a random number of strings or it goes int, int, strings then I don't know what will happen.
What if I find that it is formatted incorrectly? Use that try, catch thing? Throw an exception? Exit?
A lot of stuff I have pretty robust. I'm still putting try catch blocks where I allocate dynamic memory. And whenever an image file does not exist I just return 0's so the game keeps playing but it gets blank images. But yeah, if a file is formatted crazy, I guess I have to check for that somehow.
What if I find that it is formatted incorrectly? Use that try, catch thing? Throw an exception? Exit?
A lot of stuff I have pretty robust. I'm still putting try catch blocks where I allocate dynamic memory. And whenever an image file does not exist I just return 0's so the game keeps playing but it gets blank images. But yeah, if a file is formatted crazy, I guess I have to check for that somehow.
If you have formatted data, you can check each field individually, as well as make sure that the sequence of fields is correct (in a related note, XML schemas are used to validate XML files). If you have binary data, you'll have to rely on checksums and/or record delimiters. You'll also need, in any case, to verify that the values you receive are sensible (what that means depends on your program).
As for what to do when you find an invalid file, it is up to you - it depends in how you've designed your entire application. The main guiding principle for exception handling is to catch them where you can do something about them (which is not necessarily the point where they occur).
What happens when things are not as perfect as you expected is important (e.g. to avoid problems like denial of service), but even if you have to choose sub-obptimal behavior (e.g. shutting down the program), it's better than not knowing what happens (e.g. your machine getting pwned).
As for what to do when you find an invalid file, it is up to you - it depends in how you've designed your entire application. The main guiding principle for exception handling is to catch them where you can do something about them (which is not necessarily the point where they occur).
What happens when things are not as perfect as you expected is important (e.g. to avoid problems like denial of service), but even if you have to choose sub-obptimal behavior (e.g. shutting down the program), it's better than not knowing what happens (e.g. your machine getting pwned).
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement