49

Do I always have to specify absolute path for objects instantiated from std::fstream class? In other words, is there a way to specify just relative path to them such as project path?

IndustProg
  • 627
  • 1
  • 13
  • 33
user336359
  • 1,244
  • 1
  • 11
  • 18

8 Answers8

36

You can use relative paths as well. But they are relative to the environment you call your executable from.

This is OS dependent but all the major systems behave more or less the same AFAIK.

Windows example:

// File structure:
c:\folder\myprogram.exe
c:\myfile.txt

// Calling command from folder
c:\folder > myprogram.exe

In the above example you could access myfile.txt with "c:/myfile.txt" or "../myfile.txt". If myprogram.exe was called from the root c:\ only the absolute path would work, but instead "myfile.txt" would work.

As Rob Kennedy said in the comments there's really nothing special about paths regarding fstream. But here is a code example using a relative path:

#include <fstream>
int main() {
    std::ifstream ifs("../myfile.txt");
    ... // Do something sensible with the file
}
Kleist
  • 7,785
  • 1
  • 26
  • 30
  • How to do *what*, @User? If you have a string with a relative path in it, you can pass it to `fstream::fstream` or `fstream::open` just like you would for a string with an absolute path. – Rob Kennedy Nov 09 '11 at 17:28
19

If you have an .exe file running from C:\Users\Me and you want to write a file to C:\Users\Me\You\text.txt, then all what you need to do is to add the current path operator ., so:

std::ifstream ifs(".\\you\\myfile.txt");

will work

Samer
  • 1,923
  • 3
  • 34
  • 54
  • 1
    The hint I got from your comment, is that all projects have a default root directory, `$(SolutionDir)`, which is a macro defined in the Project Properties configuration pages. I'm assuming all relative paths begin from `$(SolutionDir)`. – tom_mai78101 Jul 07 '19 at 16:07
  • For some reason this is the answer, and I don't know why. I used `.//` to get it to work on Linux, but I was expecting `../` to work. – Andrew Jan 04 '22 at 22:00
4

You can use relative paths. They're treated the same as relative paths for any other file operations, like fopen; there's nothing special about fstream in that regard.

Exactly how they're treated is implementation-defined; they'll usually be interpretted relative to your process's current working directory, which is not necessarily the same as the directory your program's executable file lives in. Some operating systems might also provide a single working directory shared by all threads, so you might get unexpected results if a thread changes the working directory at the same time another thread tries to use a relative path.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
2

Say you have a src folder directly under your project directory and the src folder contains another tmp_folder folder which contains a txt file named readMe.txt. So the txt file can be read in this way

std::ifstream fin("../src/tmp_folder/readMe.txt");
Martin
  • 21
  • 2
1

The behaviour is OS specific. Therefore, the best way to handle this IMHO is to make it somebody else's problem. Read the path to the file to open as a string from the user (e.g: command line argument, config file, env variable etc..) then pass that string directly to the constructor of fstream. Document that this is how your program behaves.

I wrote more about path manipulation here: https://stackoverflow.com/a/40980510/2345997

Community
  • 1
  • 1
user1976
  • 353
  • 4
  • 15
1

On linux also:

// main.cpp
int main() {
    ifstream myFile("../Folder/readme.txt");
    // ...
}

Assuming the folder structure is something like this:

/usr/Douments/dev/MyProject/main.cpp /usr/Documents/dev/MyProject/Folder/readme.txt

A-Sharabiani
  • 17,750
  • 17
  • 113
  • 128
0

What I ended up using was a relative path as identified on How to open a file with relative path in C++? which ended up being:

myFile.open("../Release/frequency.dat", ios::in);

*changing myFile to whatever your variable is.

JhWebDev
  • 382
  • 7
  • 13
0

You can specify a path relative to current directory. On Windows you may call GetCurrentDirectory to retrieve current directory or call SetCurrentDirectory to set current directory. There are also some CRT functions available.

0902horn
  • 188
  • 1
  • 7