Open a file in current directory - c++

I'm trying to open a file where my program runs, I could open a file in directories like this:
myfile.open("D:\\users.txt");
But I want to open this file:
myfile.open("users.txt");
users.txt is placed where my program is.

users.txt is placed where my program is.
The current working directory of your process may not be where your program executable is. The two are not bound together.

This:
myfile.open("users.txt");
should work just fine. However, I have encountered situations where the program could not read the file. That was due to the white spaces being included within the full path:
eg: "C:\Folder1\Folder 2\file.txt"
Make sure you don't have any white spaces there...

I recommend reading up on Naming Files, Paths, and Namespaces to give you a better understanding how Win32 API handles File paths, and also Namespaces. It will help you in the long run when you need to open USB and Serial connections to external devices.

Related

Reading the command a program was called from

If this has already been answered elsewhere, I'm sorry, I couldn't find it.
I have an interesting problem whereby I have a compiled program, prog.exe, which reads a file prog.cfg which contains the config. If I open prog.exe by double-clicking on it, everything's good. However, if I open it from a command line or batch file, I first have to set the directory. For example, if I have my program in a progs folder on the desktop, and from the desktop run progs\prog.exe, it doesn't load the config because it's looking for the config on the desktop ie in the current working directory.
This is fine if you know about it, but it's just another hoop for users to jump through. Is there a way in c++ to backtrack to the command used to launch the program to deduce whether the config file will be in the current working directory or not?
Alternatively, am I asking completely the wrong question?
Many thanks!
You can use GetModuleFileName(nullptr, buf, bufsize) to get a path to the executable.
Note that the standard main function's argv[0] is not guaranteed to provide that path, and when it provides a path, is not guaranteed to provide a programmatically usable representation of the path.
if i understand you correctly, you always want your .exe read your .cfg file from the folder your .exe located? right?
try argv[0].
argv[0] is your full .exe path when you run your exe, and it is a parameter of main function.

How to use Instruments Time Profiler with Executable

I'm trying to use Mac Instruments Time Profiler to optimize my code for building a MandelBox. I found how to make my executable my target process, but when the program runs, it gives me an error in the Console window saying it cannot find the .txt file associated with the program.
Do I need to tell the profiler where to look to find the file? The text file is already in the same directory as the executable. Any thoughts? Thanks.
This problem is not unique to Instruments. The same thing would presumably happen if your current working directory was something other than the location of your program. For example, if you were to do cd / ; /path/to/yourprogram.
You either need to make your program find its own location and then find its text file as a sibling in the containing directory or take the path of the text file as an argument. Or, you will always have to set the working directory to your program's location before invoking it.
That last approach is an immediate workaround for the problem with Instruments. On the panel where you choose the target executable, you can also configure various parameters, such as arguments, environment variables, and the working directory. Set the working directory to the directory that contains the text file and it should work.

C++ How should I send project that reads specific .txt files?

I have a c++ project that I would like to send to someone in executable form. The issue is the program must read from a .txt that I created (specific deliminators). Currently my program reads from a file path that is specific to my computer,
parseFile("/Users/David/Desktop/FinalProject/Store.txt");
How could I package the .txt file and the executable file together, where the exec. reads specifically from the that .txt on anyone's machine?
Note: I am using Xcode
Change your programs to receive 'file path' as a parameter. Write a note(ReadMe) with the program to specify the file format and added a sample data file with the package
tl;dr: if you just put the text file in the same folder with your executable, you can open it with parseFile("Store.txt");
In most runtime implementations, there is a notion of a "working directory." When you open up an executable via the graphical shell (by double clicking it or something to that effect) the working directory is the same as the directory the executable is in.
Now, if you try to open a file in your program via a path that isn't fully qualified, then the path that gets used will be relative to the working directory.
A fully qualified path is a discrete path that points to a single entity in your filesystem. "/Users/David/Desktop/FinalProject/Store.txt" is one such example, as it starts at root (/ on *nix, DriveLetter:\ on Windows) and says exactly which directories you need to traverse to get to your file.
A path that is not fully qualified (which basically means that it doesn't start at the root of your filesystem) can be used to perform relative file addressing. Most runtimes will assume that any path that is not fully qualified is meant to be relative to the working directory, which basically means that the path that actually gets opened is the result of concatenating your provided path to the end of the working directory.
As an example, if you opened your binary, which is stored as /Users/David/Desktop/FinalProject/a.exe, then the working directory would be set to /Users/David/Desktop/FinalProject/. If your program then tried to open "Store.txt", the runtime would see that you're trying to open a path that isn't fully qualified, so it would assume you meant to open a file relative to the working directory, which would then be /Users/David/Desktop/FinalProject/ + Store.txt, which would be /Users/David/Desktop/FinalProject/Store.txt.
The nice thing about this is that if you move your binary, the working directory moves too. if you move a.exe along with Store.txt to /Users/David/Desktop/FinalProject(copy)/, then when you open /Users/David/Desktop/FinalProject(copy)/a.exe, the working directory will be /Users/David/Desktop/FinalProject(copy)/ now, and now when you call parseFile("Store.txt"), it will instead open up /Users/David/Desktop/FinalProject(copy)/Store.txt. This holds true when moving to other computers, too.
It's worth noting that if your binary is run from a command line utility, the working directory will often be the directory the command line shell is in, rather than the executable's directory. It is, however, a part of the C standard that the first command line parameter to main() should be the name of the executable, and most implementations supply you with the fully qualified path. With some minimal parsing, you can use that to determine what path to use as a base for addressing files.

How to reference a file to be opened in C++ given that its full path name will change from computer to computer?

Our Computer Science teacher has given us a project to make a fully functioning console application using C++. And I have started to make it. But I got stuck at some point. I want to open an editable text (.txt) file using the open() function. But I made a separate folder for all the text files. Usually I have to provide a full directory path in the open() function, which is F:\Work\C++\SchoolProject\TextFiles in my case. But what if I copy the SchoolProject folder in a portable drive and take it to my friend's home and try to run the program in their computer. Will it work? I'm asking because it is not necessary that they will have the Work folder in the F directory or maybe they may not have the F disk at all. So in that case the path will change. So what path I have to type in the open() function so that the program works in each and every computer without changing the address in the open() function every time I try to run the program in some other computer. A source code may be helpful with explanation. Thank You!
Instead of using absolute paths, you should use relative paths. When you run your program from a folder, this is your working path. You can then open files inside this folder or subfolders of this folder by passing only the file name or folder and file name to the open function. So instead of opening C:\... simply open someFolder\someFile.txt.
You could consider having the filename that you parse in as part of a command line argument, like this:
int main(int arg, char* args[]) {
FILE *newfile = fopen( args[1], "r");
}
You can not be sure all computers have the F: drive mapped correctly so it is better to use
Universal Naming Convention (UNC) names i.e. "\server\share\path\file".
A nice way to achieve the same is by using Boost Filesystem, but this makes your code more complicated since you are depending on an external library (read: the students might be confused). The documentation for Boost Filesystem is found here: http://www.boost.org/doc/libs/1_43_0/libs/filesystem/doc/index.htm

std::ifstream::open() not working

I am developing a prototype for a game, and certain gameplay rules are to be defined in an ini file so that the game designers can tweak the game parameters without requiring help from me in addition to a re-compile. This is what I'm doing currently:
std::ifstream stream;
stream.open("rules.ini");
if (!stream.is_open())
{
throw new std::exception("Rule file could not be opened");
}
// read file contents here
stream.close();
However, my stream never opens succesfully. Diving deep into the STL source during debugging reveals that _getstream() (as defined in stream.c) keeps on returning NULL, but I just can't figure out why this is. Help, anyone?
Edit: Rules.ini is in the same directory as the .exe file.
You are assuming that the working directory is the directory that your executable resides in. That is a bad assumption.
Your executable can be run from any working directory, so it's usually a bad idea to hard-code relative paths in your software.
If you want to be able to access files relative to the location of your executable, you should first determine the path of your executable and create a fully qualified path from that.
You can get the name of your executable by examining the argv[0] parameter passed to main(). Alternatively, if you're on Windows, you can get it with GetModuleFileName() by passing NULL as the first parameter.
Is the scope of your open stream correct.
"rules.ini" isn't a full path so it has to be relative so what is it relative to. Or do you need to use full path there.
(wild assumption here) you are using visual studio. During debug, your program is going to search the project directory for "rules.ini"
However, if you try executing your program from "myproject/debug/myexe.exe", it should run fine because it is going to search "/debug" for rules.ini
Like its been mentionned you should specify the full path because relative path tend to lead to errors