-1

I wrote a method which takes in a file name, checks if the file exists and has content, then proceeds to read 6 numbers in the file into 6 int variables and return true. If the file doesn't exist, or doesn't have content, it returns false.

However, when I call the method and give it a file that exists, it returns false. I'm not sure where I went wrong.

Here's my code:

bool readHSV(string the_file)
{
    if(ifstream(the_file)){
        fstream myfile(the_file, ios_base::in);
        myfile >> h_min >> h_max >> s_min >> s_max >> v_min >> v_max;
        cout << h_min << endl << h_max << endl << s_min << endl << s_max
        << endl << v_min << endl << v_max;
        getchar();
        return true;
    }
    return false;
}

The contents of the .txt file I am using:

4
22
68
192
162
247
J. Doe
  • 11
  • 1
  • 2

2 Answers2

1

The only way your function can return false is if ifstream(the_file) fails, meaning it can't open the file at all, whether it exists or not. If the file does exist but ifstream still fails, double check that the_file contains the correct path and filename, and that your app has rights to access the file.

Note that you are opening the file twice, once by ifstream and again by fstream. You don't need to do that. You should open the file only once, and return true if you are able to read the values you want from it, eg:

bool readHSV(const string &the_file)
{
    ifstream inFile(the_file);
    if (inFile >> h_min >> h_max >> s_min >> s_max >> v_min >> v_max)
    {
        cout << h_min << endl
             << h_max << endl
             << s_min << endl
             << s_max << endl
             << v_min << endl
             << v_max;
        getchar();
        return true;
    }
    return false;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank you for your response! When I input a valid file into the function, it still returns false even though it should have returned true. Is it the way my file is formatted? I edited my question to show what the contents of the file are. Thanks again! – J. Doe Dec 19 '18 at 05:41
  • "*When I input a valid file into the function, it still returns false even though it should have returned true*" - there are only 2 ways this code can fail: 1) the file can't be opened (`inFile.is_open()` returns false), or 2) the integers can't be read from the file (`inFile.fail()` returns true after calling `operator>>`). "*Is it the way my file is formatted?*" - it should not be, as `operator>>` ignores whitespace, including line breaks. I see nothing wrong with the file data, or the reading code, so you are just going to have to debug the code to find out what is actually failing. – Remy Lebeau Dec 19 '18 at 17:43
0

You can use <filesystem> like this:

#include <filesystem>

namespace fs = std::filesystem; // for brevity

// ...

bool func(std::string const& filename)
{
    if(!fs::exists(filename) || fs::file_size(filename) == 0)
        return false;

    std::ifstream ifs(filename);

    if(!ifs)
        return false;

    // do stuff here with ifs

    return true;
}
Galik
  • 47,303
  • 4
  • 80
  • 117
  • This creates an unnecessary race condition between `exists()`, `file_size()`, and `ifstream`, if `exists()` returns true and then the file is moved/deleted before `file_size()` or `ifstream` are called. You don't need `exists()`, by virtue that `ifstream` will fail anyway if the file does not exist. If `ifstream` is successful in opening the file, then the file obviously exists, and you can then query the file size from it if needed, or simply ignore the size and proceed to read values and check if they fail. – Remy Lebeau Dec 08 '18 at 03:25
  • @RemyLebeau Its for exposition only. It gives the modern approach to answering both OPs questions. But as for race condition? You can just as likely get such a race condition between one `>>` call and the next. On most operating systems files can theoretically be deleted from under your feet by other processes. But usually you control such access to the files your program manages, or else it is the responsibility of the **user** not to delete the same file he is already using. – Galik Dec 08 '18 at 03:52
  • 1) on modern systems, a file is usually not actually deleted from the filesystem until all open handles to the file have been closed first, and 2) the standard library does not allow for this, but on some systems you can open a file with restrictive permissions about what other people are allowed to do with the file while you have it open, like deny access to deleting it. – Remy Lebeau Dec 08 '18 at 04:01
  • @RemyLebeau On systems since time immemorial no other user can delete your files because the OS won't let them. So if your files get deleted its because you deleted them. That's probably why the standard library doesn't really care about this. – Galik Dec 08 '18 at 04:07