0

I try to handle the cases when I try to write a file that already exists by adding plus ID to the filename. In short it's something like what Windows does when I copy a file.

Assuming I have a file test.bmp. I want to apply a filter on it and save the filtered image as testout.bmp. But the testout.bmp already exists in that folder, so the program catches this and save it as testout(1).bmp for example. In my code I try to use exeptions. My idea is something like this: (pseudo code)

bool IMAGE_DATA::openFile(const char* filename)
{
    int i = 0;
    try
    {
        if(file_exists(filename)) throw whatever;
    }
    catch(type whatever)
    {
        changefilename(filename,i)
        i++;
        if(file_exists(filename)) /* throw whatever/do something */;
    }
};

Currently if the file already exists, my program only exists (file_exists just returns true when there's a file with that name in the folder).

I started to redesign my base function with exception handling instead of simply returning false if any error occurred. I wrote whatever here because I will have more throws (if if the file cannot be opened or exists but the same as my file ect.).

How can I try and catch file names until there's a file name that's correct. Or is there any easier method for this and I should not use exceptions? What is the best design to handle this problem?

David Szalai
  • 2,363
  • 28
  • 47

2 Answers2

2

I can't quite grasp why you would use exceptions for this. Exceptions as flow control is considered very poor style, apart from some very specific idioms. Throwing and catching anything that isn't derived from std::exception is also a no-no. Plus, your posted code isn't even close to compiling, so my answer is also in pseudo-code. One more thing, why use char* for the name and not std::string?

Would this do what you required?

bool IMAGE_DATA::openFile(std::string filename)
{
    while(file_exists(filename))
    {
        filename = add_1_to_filename(filename);
    }

    open(filename);
}
  • 2
    +1, [here](http://stackoverflow.com/a/18073392/33499) is a more complete implementation, but it uses Qt – wimh Dec 14 '13 at 11:18
  • so exceptions are not for this. But I read _Exception handling is needed to identify problems that program cannot handle and tell them about the user, because user can handle them._ from this http://stackoverflow.com/questions/4506369/when-and-how-should-i-use-exception-handling?rq=1. Then if I use a message box and request the user to input another name could or could not be handled by exception. (+1 for both) – David Szalai Dec 14 '13 at 11:25
  • 1
    @PnDs But it's not an unexpected problem. It's very much expected that file_exists could return true or false - that's what it's for. And you are dealing with the issue. If you could find no appropriate filename at all no matter what you tried, THEN throw an exception! Further up in the program, this might then show a message box, or otherwise notify the user gracefully. –  Dec 14 '13 at 11:29
  • 1
    Thanks, now I understand. Sometimes I don't use the proper design to write my codes, when I learn something new I try to use that too often. That's not a good practice. Also I've just ported this code from C to c++, so I have to replace the old C-style things (like char* to ::std::string). – David Szalai Dec 14 '13 at 11:40
  • 1
    Good man. Note in my code I passed std::string by value. This was only so I could write some brief code which assigned back to the parameter variable. Normally, you would pass strings by const reference, if you're not going to modify them. –  Dec 14 '13 at 11:42
1

In your scenario, having an existing file is no exception. Hence, do not use them. If you are trying pass additional information around you may use a functor:

#include <iostream>

struct FileExits {
    bool value;
    std::string information;

    FileExits(const std::string& name)
    :   value(true), information("Test")
    {}

    operator bool () const { return value; }
};

int main() {
    // Endless loop in this example
    std::string name;
    while(FileExits result = name) {
        std::cout << result.information << std::endl;
    }
    // ...
    return 0;
}