Search code examples
c++fstreamifstream

C++ problem trying to open a .txt file using Ifstream


This small bit of code is designed to look through a text file and identify account numbers that have already been written so that later on in my program, you can find the correct account without the error of two accounts with the same account number(id). But no matter what i do, whether its using double backslashes, forward slashes, or double forward slashes in the location for the ifstream object; i always get "cannot find file" as the output.

#include <iostream>
#include <fstream>
using namespace std;

int main() {
    ifstream accountsread("‪G:/Coding/Test/test/test/accounts.txt");
    if (accountsread.is_open()) {
        int tempAccno;
        std::string tempname;
        char tempchar;
        int accountsfound = 0;
        int input;

std::cout << "Enter the ID of the account \n";
        cin >> x;

        while (!accountsread.eof()) {
            accountsread >> tempAccno;
            if (tempAccno == input) {
                accountsfound++;
            }
            else {}


        }
        if (accountsfound > 0) {
            cout << "number found";
        }
        else {
            cout << "number not found";
        }
    }
    else {
        cout << "cannot find file";
    }
}

in windows, the location of the text file is ‪G:\Coding\Test\test\test\accounts.txt


Solution

  • std::ifstream can use relative paths as well as absolute ones. For your problem, I'd recommend looking into the <filesystem> header from the STL if you really need an absolute path to your file. However, if it's in the same directory as your working directory, you don't need to use absolute paths. Here's how I'd accomplish your task

    #include <iostream>
    #include <fstream>
    #include <string>  // Should include since you're using std::string
    
    // Note that I am NOT "using namespace std;"
    
    int main()
    {
        std::ifstream accountsRead("accounts.txt");
        if (accountsRead.is_open())
        {
            int account_id;
            bool account_found = false;
    
            std::cout << "Enter the ID of the account: ";
            while (!(std::cin >> account_id))
            { // This loop handles if the user inputs non-number
                std::cout << "Please enter a NUMBER below!\n";
                std::cout << "Enter: ";
                std::cin.ignore(10000, '\n');
                std::cin.clear();
            }
            
            int tmpAccNum;
            while (accountsRead >> tmpAccNum)
            { // This loop reads the file, line by line, into tmpAccNum
                if (tmpAccNum == account_id)
                {
                    account_found = true;
                    break;
                }
            }
    
            if (account_found)
            {
                std::cout << "Number found!" << std::endl;
            }
            else
            {
                std::cout << "Number not found..." << std::endl;
            }
        }
        else
        { // Error opening file
            std::cout << "File not found or is corrupted" << std::endl;
        }
    }
    

    A few things about your code stylistically speaking. First, you should never be using namespace std, and (if you are for some reason) there isn't a reason to mix and match specifying the std namespace on only some std members. Second, you don't need to specify an else for every if-statement, and you probably shouldn't unless there actually are commands to execute if the else case is reached.

    Edit

    If you still need an absolute path, here is how you can do that:

    #include <filesystem>
    
    int main()
    {
        // Create path object for the file path
        std::filesystem::path file_path("G:\Coding\Test\test\test\accounts.txt");
    
        // The '.string()' method for a 'std::path' object returns the string
        // version of the path, so you can use it with an 'std::ifstream'
        std::ifstream accounts(file_path.string());  // Opens file via 'ifstream'
        /* And so on... */
    }