i found C++ libraries could be included this way:
#include "..\example.h"
#include ".\another_example.h"
what is the dots used for?
They are to indicate the included file paths' are relative to the including file's actual path.
. points to the including file's actual directory
.. points to the including file's actual directories' parent diretory
Double dots stand for the parent directory of the currently entered path.
Single dot stands for the currently entered path on the left side of a dot and is used to show that you want a relative path.
A relative path is a path relative to the working directory of the
user or application, so the full absolute path will not have to be
given.
If you start your path with / (on *nix systems) or DRIVELETTER: (on Windows, e.g. D:) then the path is absolute. If you don't - the path is relative. If path is relative - it automatically prepends the directory of your file to the path entered.
Example:
"dir/././../dir/.." is the directory which contains the original file. The reductions are:
dir/././../dir/.. -> dir/./../dir/.. -> dir/../dir/.. -> /dir/.. -> . -> working directory. We removed ./ because it's alias to the current directory. We removed /dir/.. because we enter a directory with dir and get back with ..
One of the most often used features of ./ (but in the context of a shell, e.g. bash) - it forces to use a relative path instead of calling an executable program in the $PATH variable. For example if you type ls in terminal on *nix it will list the files in the working directory. If you type ./ls it will run executable with the name ls
in the current working directory and execute whatever this program does.
You can read more about path separators in this article on wikipedia
One dot is your current directory and two dots is your parent directory.
Two dots means one directory higher than the current one. For example, if you are in the directory C:\some\directory", "..\" would be "C:\some".
A single dot refers to the current directory. So using the previous example, ".\" would mean "C:\some\directory".
one dot . is for file's directory
2 dots .. are for file's parent directory.
Related
I have the feeling the C++ filesystem standard is broken on windows. It is heavily based on Boost.filesystem and I just found a serious issue there which (likely) also exists in std::filesystem: https://github.com/boostorg/filesystem/issues/99
The essence is the definition of "root_name" and "root_directory":
root-name(optional): identifies the root on a filesystem with multiple roots (such as "C:" or "//myserver"). In case of ambiguity, the longest sequence of characters that forms a valid root-name is treated as the root-name. The standard library may define additional root-names besides the ones understood by the OS API.
root-directory(optional): a directory separator that, if present, marks this path as absolute. If it is missing (and the first element other than the root name is a file name), then the path is relative and requires another path as the starting location to resolve to a file name.
This requires e.g. "C:\foo\bar.txt" to be decomposed into:
root_name: "C:"
root_directory: "\" or "/" (does this even make sense?)
directory: "foo"
file_name "bar.txt"
The problem now: The first part of this path is not a path, at least not the original one. This comes from the interpretation on windows:
"C:\" is the drive "C"
"C:" is the current working directory on the drive "C"
Minor: How should "\foo\bar.txt" be interpreted on windows according to the above? You have a "root_directory" (which is strangely not a directory but a directory separator) but no "root_name" hence the path cannot be absolute and so you don't have a "root_directory" either. sigh.
So from this I feel that "root_name" and "root_directory" cannot be decomposed (on windows). In "C:\foo" you'll have "C:\" and in "C:foo" you'll have "C:". Or to keep the (strangely defined) "root_directory" you'd need to set decompose "C:\foo" into "C:\", "\" and "foo" and struggle with the latter: Is that an absolute path? Actually it is: "The folder 'foo' in the current working directory on drive C", quite absolute, isn't it?
But well you could say "absolute==independent of current working dir" then the "root_directory" makes sense: It would be "\" for "C:\foo" and empty for "C:foo".
So question: Is the standard wrong in defining "C:" as the "root_name" instead of "C:\" in paths like "C:\foo" or is it simply invalid usage to iterate over components of a path expecting the prefix sums to be "valid"?
Your interpretation of the Windows filesystem is incorrect. The directory C:\ is the root directory of the "C" drive, not "the drive 'C'". This is distinct from C:, which is the current directory of the "C" drive. Just try using the Windows shell and see how C:<stuff> behaves relative to C:\<stuff>. Both will access stuff on that drive, but both will do so starting from different directories.
Think of it in these terms on Windows:
C: means "Go to the current directory of the C drive".
\ at the start of a path (after any root names) means "Go to the root directory of the current drive".
foo\ means "Go into the directory called 'foo' within whatever directory we are currently in".
bar.txt means "The file named 'bar.txt' in whatever directory we are currently in."
Therefore, C:\foo\bar.txt" means: Go to the current directory of the C drive, then go to the root directory of C, then go into the 'foo' directory of the root directory of C, then access the file 'bar.txt' in the 'foo' directory of the root directory of C.
Similarly, C:foo\bar.txt means: Go to the current directory of the C drive, then go into the 'foo' directory of the current directory of C, then access the file 'bar.txt' in the 'foo' directory of the current directory of C.
This is how Windows paths work. This is what it means to type those things in the Windows shell. And thus, this is how Boost/std filesystem paths were designed to work.
But well you could say "absolute==independent of current working dir"
But that's not how std filesystem defines the concept of "absolute path":
Absolute Path A path that unambiguously identifies the location of a file without reference to an additional starting location. The elements of a path that determine if it is absolute are operating system dependent.
So "relative" and "absolute" are implementation-dependent. In Windows, a path is not absolute unless it contains both a root-name and a root-directory. In the Windows filesystem implementation, path("\foo\bar.txt").is_absolute() will be false.
What you're looking for is root_path, see Filesystem TS § 8.4.9, path decomposition:
path root_path() const;
Returns: root_name() / root_directory()
Here's how Microsoft defines it:
Common to both systems is the structure imposed on a pathname once you
get past the root name. For the pathname c:/abc/xyz/def.ext:
The root name is c:.
The root directory is /.
The root path is c:/.
The relative path is abc/xyz/def.ext.
The parent path is c:/abc/xyz.
The filename is def.ext.
The stem is def.
The extension is .ext.
So a truly absolute path would begin with root_name + root_directory, or root_path.
See also system_complete(p) for resolving current directory on other drives:
Effects: Composes an absolute path from p, using the same rules used by the operating system to resolve a path passed as the filename argument to standard library open functions.
[Example: For POSIX based operating systems, system_complete(p) has the same semantics as absolute(p, current_path()).
For Windows based operating systems, system_complete(p) has the same semantics as
absolute(p, current_path()) if p.is_absolute() || !p.has_root_name() or p and
base have the same root_name(). Otherwise it acts like absolute(p, cwd) is the current directory for the p.root_name() drive. This will be the current directory for that drive the last time it was set, and thus may be residue left over from a prior program run by the command processor. Although these semantics are useful, they may be surprising. —end example]
I'm trying to load files, and previously I was using hardcoded file locations, (like "c:\location\file.txt") but now that a few friends are also using the file, I'd like to allow them to put the executable wherever they want.
my current code looks like:
ifstream myfile;
myfile.open("c:\\client\\settings.cfg");
I'm trying to change it so that the user puts their executable into whatever folder they want, and then they create a folder and put their settings file into it and the exe will load that with their settings.
ifstream myfile;
myfile.open("\\settings\\settings.cfg");
I have some basic error handling in place, and now the program always errors out saying that it can't find the file.
The file structure looks like this:
[ART]
asset.png
[SETTINGS]
settings.cfg
client.exe
This seems like a really simple thing to do, but I can't find any way to do it. Every example and tutorial about reading and writing to files deals only with files in the executable's directory, or hardcoded into c:\folder...
Could anyone point me to how I do this?
The search path for most systems starts with the current working directory and then to a PATH environment variable. So, all you need to do is specify the file/folder without the absolute path markings and it will use the path relative to the working directory:
ifstream myfile;
myfile.open("settings\\settings.cfg");
// ^^ Note the lack of \\ to start the file path
Paths beginning with \ are always relative to the current drive's root directory. If the current drive is C:, then \settings\settings.cfg means C:\settings\settings.cfg.
Note that you can use / in order to avoid escaping everything. So you can use: settings/settings.cfg. This will be relative to the user's current directory. Note however, that this doesn't necessarily correspond to the directory where the executable resides. If you need the directory of the executable, then you need to use a Windows API function to get it:
#include <Windows.h>
// ...
HMODULE module = GetModuleHandleW(NULL);
WCHAR path[MAX_PATH];
GetModuleFileNameW(module, path, MAX_PATH);
Now if you want to open settings/settings.cfg relative to the directory of the executable, create a path that starts with path and append /settings/settings.cfg to it.
I am have a trouble in using fopen() with relative path. I wanted to use fopen like this:
fopen("\\Saurabh\\pqrs.txt");
i am getting filePointer as null.
The situation arose because I am trying to create a setup or deployment project which has to read files. The file paths chosen by default after user executes setup are C:\Program Files\Setup..
(where exe is dumped). So I dumped the files in the same folder and gave path(fixed path or hardcoded) to those files in the program.
If the user selects some other path for installation, the program fails.
Is there any way I can fix this?
Two problems:
You need to escape the backslash character. Write \\.
You need to use a relative path. By starting a path with \\ you mean start from the root directory.
Putting these together, I think you should write:
fopen("Saurabh\\pqrs.txt");
Make sure you double up the \ characters. The string you're passing in should be "Saurabh\\pqrs.txt". Note that beginning a path with \\ means that it's not relative. (Well, actually it's relative to your current drive, but I doubt that's what you're looking for.)
This is workig:
I have my exe in the same directory as Images folder;
Main:
|-Images
|-cross_ball
|-frame.bmp
|-game.exe
I'm refering to frame.bmp in my game.exe.
This path is workig good: "Images\\cross_ball\\frame.bmp"
This is not working:
Exe is in bin folder. bin folder is in the same folder as Images folder;
Main:
|-Images
|-cross_ball
|-frame.bmp
|-bin
|-game.exe
This path is not working: "..\\Images\\cross_ball\\frame.bmp"
If "Images\cross_ball\frame.bmp" is working, then your app's current directory isn't the Images directory like you think it is. It must be one dir up for that to work. That would also explain why moving the exe to the bin directory fails.
Are you starting your app from a shortcut or in a debugger? Shortcuts and debuggers specify the app's current directory, which isn't necessarily the same directory the exe is in.
As an experiment, replace each \ by \\ and test again.
Back slash is generally used for escape sequences like '\n'.
By putting two of them together, the run time ought to change them into one.
"Images\\cross_ball\\frame.bmp"
It appears that your logic is fine. Are you sure your process hasn't changed the current working directory - i.e. Main/bin/ might not be your working directory when you go to make this change in the executable.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 12 years ago.
Improve this question
If you look at point (6) here: http://www2.warwick.ac.uk/fac/sci/moac/students/peter_cock/cygwin/part3/
Why should we type ./ before the .exe file in order for it to run?
Why cannot we type hello.exe immediately?
Thanks.
Usually because intelligent people don't have their current directory . on the path :-)
The path is an environment variable like /bin:/usr/bin:/usr/sbin, and it's a list of directories to look in for finding executables, such as when you type in hello.
Unlike Windows, many UNIX shells don't automatically search the current directory for an executable. They must be listed in the path otherwise they are not run.
That's because to do otherwise is actually an attack vector. For example, if you create an ls program in your home directory and tell one of the administrators that there's a funny file in there, they may go to your directory and enter ls to see what's in there.
For a silly administrator that has the current directory before the "real" location of ls, they are now compromised, because your code is running with their full privileges.
That's why they tend not to do that.
Some people (not I) will put . on their path to make their lives easier but, even then, they'll put it at the end so that other locations are searched first.
Administrators don't have the luxury of being that trusting.
Because the current working directory is not in the PATH?
Or at least, that's how things are setup on Unix-style systems, I assume CYGWIN does the same.
On Windows, the current directory is always in the search path for an executable. The search order is "look in the current dir, if not found, look in the directories listed in the PATH environment variable".
From MS site:
The operating system always searches
in the current directory first, before
it searches the directories in the
command path.
(which makes all the warning here of not putting the . in your PATH irrelevant, IMHO)
On Linux this is not the case (for current dir). So, to run an executable which is in your current dir you need to write ./exe_name.
As Cygwin, again AFAIK, is for Windows, the ./ is not needed and seems to be just a copy/paste or preserving the unix-style the writer is used to.
EDIT: this is the issue of the command processor (the shell) as pointed out in comments and as I explain below, so if you are using a Unix-like shell on Windows, you still may need this style.
EDIT: elaborating on .\
. (not ./ to be exact) is an alias to the current directory. On Unix, every newly created directory is not "born" empty but contains 2 children: ., which is a self-reference, and .. which is a reference to the parent directory. Both are just regular directories, as any other. You don't see them when you run the ls command (same as dir on Windows) because names starting with . are special in the sense that they are not displayed by default. However, you can see them by ls -a.
When you run a command at the prompt, if the command is only a (file) name, the system (actually, the shell) searches the PATH for the file with this name.
If the command contains a path (not necessarily an absolute path, e.g. subdir1/exe) the system looks for the executable where you specified. Hence, writing ./exe means file exe in the current dir.
Cygwin is a Unix-like runtime environment and as such follows the way paths are searched for executables in such environments. The default executable search path of Unices does not contain the current directory. Thus if one wants to run an executable not located in one of the directories set in PATH a full path must be given. ./ is a shorthand for the current directory, also called process working directory (pwd). Be advised that it's a very bad idea to have the pwd being included in the executable search path.
Cygwin follows the Unix limitations on executing files in the current working directory. In Unix style terminal environments an executable must have ./ prepended if it is to be executed from the current directory. This is because the current directory "." is not part of the PATH environmment in order to limit the damage done by malware. Cygwin is simply following this convention, it has nothing per say to do with C++ programs
That's just an issue with your 'path' or 'PATH' variable in your shell. (probably your shell is bash, so it'd be PATH.)
echo $PATH
A typical 'user' path to do what you want would start with "." as a path element. This is a minor security risk of course.