C++ get source file directory in Linux - c++

This question is many time asked and I referred all, but I need bit different.
I am using macbook -> Clion (IDE) for C++
My program file location
/Users/Kandarp/ClionProjects/SimulationParser/main.cpp
When I use following function for get current directory it gives different file (I think actual path where file is compiled and execute)
string ExePath() {
char cwd[1024];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
fprintf(stdout, "Current working dir: %s\n", cwd);
return cwd;
} else {
perror("getcwd() error");
return 0;
}}
it gives following answer:
/Users/Kandarp/Library/Caches/CLion2016.2/cmake/generated/SimulationParser-50b8dc0e/50b8dc0e/Debug
But I need path where my .cpp file reside.What I am doing wrong ?
Please help

You're doing nothing wrong.
getcwd() gives you the current directory of the executing process.
When you instruct whatever tool you're using to build your C++ code to run it, it simply runs the process from that directory.
There is nothing in the C++ library that tells the application the location of its source code.
If you need your application to know where its source code lives, you need to pass that either as an argument to main(), or put it into some configuration file, that your application reads, or any similar approach.

What you want to do is use the __FILE__ macro, and then use basic tokenization to extract the directory name.
Your method does not work since during execution, the current directory is that of the binary, not of the compilation unit.

Related

File path issue in C++ program when executing from a shell script on Linux [duplicate]

Hey, I've been writing a program (a sort of e-Book viewing type thing) and it loads text files from a folder within the folder of which the executable is located. This gives me a bit of a problem since if I run the program from another directory with the command "./folder/folder/program" for example, my program will not find the text, because the working directory isn't correct. I cannot have an absolute directory because I would like the program to be portable. Is there any way to get the precise directory that the executable is running from even if it has been run from a different directory. I've heard could combine argc[0] and getcwd() but argc is truncated when there is a space in the directory, (I think?) so I would like to avoid that if possible.
I'm on Linux using g++, Thanx in advance
EDIT - don't use getcwd(), it's just where the user is not where the executable is.
See here for details.
On linux /proc/<pid>/exe or /proc/self/exe should be a symbolic link to your executable. Like others, I think the more important question is "why do you need this?" It's not really UNIX form to use the executable path to find ancillary files. Instead you use an environment variable or a default location, or follow one of the other conventions for finding the location of ancillary files (ie, ~/.<myapp>rc).
When you add a book to your library you can remember its absolute path.
It is not a bad when your program rely on the fact that it will be launched from the working dir and not from some other dir. That's why there are all kinds of "links" with "working dir" parameter.
You don't have to handle such situations in the way you want. Just check if all necessary files and dirs structure are in place and log an error with the instructions if they are not.
Or every time when your program starts and doesn't find necessary files the program can ask to point the path to the Books Library.
I still don't see the reason to know your current dir name.
#include <boost/filesystem/convenience.hpp>
#include <iostream>
#include <ostream>
int main(int argc, char** argv)
{
boost::filesystem::path argvPath( argv[0] );
boost::filesystem::path executablePath( argvPath.parent_path() );
boost::filesystem::path runPath( boost::filesystem::initial_path() );
std::cout << executablePath << std::endl;
std::cout << runPath << std::endl;
return 0;
}
You can get the path of the running program by reading the command line. In linux you can get the command line by reading /proc folder as /proc/PID/CommandLine
argv[0] is not truncated when there are spaces. However, it will only have the program name and not the path when a program is run from a directory listed in the PATH environment variable.
In any case, what you are trying to do here is not good design for a Unix/Linux program. Data files are not stored in the same directory as program files because doing so makes it difficult to apply proper security policies.
The best way to get what you want in my opinion is to use a shell script to launch the actual program. This is very similar to how Firefox launches on Linux systems. The shell places the name of the script into $0 and this variable will always have a path. Then you can use an environment variable or command line argument to give your program the location of the data files, like this:
dir=`dirname "$0"`
cd "$dir/../data/"
"$dir/real-program"
And I would arrange your program so that it's files are somewhat like this:
install-dir/bin/program
install-dir/bin/real-program
install-dir/etc/config
install-dir/data/book-file.mobi

Where would incorrectly named files (rename without specifying the path) be moved to?

I accidentally made a big blunder:
In my C++ program, I did:
std::string oldFilePath = "/Users/blah/somepath/foo.xml";
std::string newFileName = "foo.xml" //Blunder! Forgot to prefix the new path!
int status = rename(oldFilePath.c_str(), newFileName.c_str());
I forgot to prefix the new path, and just put the filename (without a path) for the new name that the file should be renamed to. As a result the file has vanished from the old path, and I don't know where its gone to!
Where is the file ? Is there a way to recover it ? (Time Machine is disabled for this folder, so I can't do that!)
EDIT: Where would the compiled file generated by Xcode for a C++ application be ?
EDIT: If you're running the program through xcode, it should be in:
~/Library/Developer/Xcode/DerivedData//Build/Products/Debug/
Don't forget the ~ in the above path!
If the operation succeeded (status == 0), the file would be in the current directory of the process when it was run. It is hard to predict where that might be, but $HOME is one plausible candidate (maybe /Users/blah/foo.xml). You should be able to find it, either with the find command or with Spotlight.
I don't use the XCode UI (or other IDEs), in part because I don't like the lack of control over things like 'where the program is put' and 'what is the current directory when I run the program' (and for the rest because I'm a dinosaur). AFAIK, the executable should be in a directory underneath the folder where you created the project. Again, Spotlight or find should be able to help you, at least if you chose a distinctive name for the program. The project directory is another place to look for the foo.xml file too.

Can't open text file resource in Xcode 4 c++ tool?

I am working on figuring out how to use Xcode 4 to debug c++ projects.
I have basically copy pasted a working c++ executable that when compiled from the terminal ran fine.
However, i was thinking it might be nice to use Xcode for debugging. So I am trying to migrate the single .cpp file into Xcode as a command line tool.
I need to read in a file called numbers.txt (which I supply through a command line argument) which is located in my project directory, and then out put to a file (whose name I also specify as an argument.)
The problem I am running into is that the files that are supplied as command line arguments are failing to open.
ifstream in;
ofstream out;
in.open(argv[1]);
out.open(argv[2]);
I have checked to make sure that the arguments are being properly passed and are named correctly. The ifstream in is being supplied with `numbers.txt', which I want to open a text file that I already have.
However when I check to make sure the ifstream is open:
if(in.is_open() == false){
cerr << "Unable to open input file" << endl;
return 1;
}
I get the error.
I suspect this has something to do with how Xcode organizes the project.
my numbers.txt file is just sitting in the Xcode project folder, and I have only one .cpp class and one product, the executable.
anyone know what I am missing here?
The executable built by Xcode is in a different folder than the project. Passing in the name of the file without an absolute path before it will cause the executable to look for it in the wrong place, which is why it can't be found. Some of the possible solutions are to include the file as part of the build process (so it ends up in the same directory as the executable) or to pass the file to be opened by its absolute path. There are other ways to solve the problem, too, but hopefully that should be enough to get you started.
Old thread, but i have faced the same problem now, and it is easy to solve. Just copy the file in the build phase.
Here is an screenshot of the final result (note the destination, subpath and checkbox):

Not able to write to a file

My programs have been running properly for over a year. Today I copied the files onto a different system and compiled every program.
When I compile and run from Dev-c++ it writes data onto a text file like its supposed to, but when I click on the executable it creates, it does not write data onto the file. Everything else like input/output seems to work.
What procedure have I missed?
Ok i've given the program Full permision but it still does not write.
I'm quite puzzled, atleast if it didn't run when i compile it in the C++ environment i can keep checking my code, but only the .exe does not work, any other suggestions ?
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream bss2;
bss2.open("expat.txt",ios::app);
bss2 << 2 ;
bss2.close();
}
This is the sample code i tested out.
How do i find the Current working directory ?
Ok i changed a line to
bss2.open("c:\\expat2.txt",ios::app);
and now it works properly in the exe file.
but there's over 50 files and i prefer i didn't have to spell out the new path to each one, what workaround is there to set the directory to the one previously used ?
update 4 :
#define _POSIX_SOURCE
#include <unistd.h>
#undef _POSIX_SOURCE
#include <stdio.h>
main() {
char cwd[256];
int y;
if (chdir("/tmp") != 0)
perror("chdir() error()");
else {
if (getcwd(cwd, sizeof(cwd)) == NULL)
perror("getcwd() error");
else
printf("current working directory is: %s\n", cwd);
}
scanf(y);
}
Ok i used the getcwd() and this is the message it gives me
chdir() error(): No such file or directory
How do i set the directory now.
Sounds like your working directory isn't being set correctly when you double-click on the file. If you can access a log, use getcwd() and log what it returns.
I don't have Raymond Chen's psychic debugging powers yet, but I do know of a tool that may help you: Process Monitor. Use it to see precisely which files your application is trying to write to, and why it fails.
Maybe your looking at the wrong location. The program will write the file to the current working directory, which may be different between when you double click on the executable and run from Dev-C++.
The best and easiest way is to give the full path of the output file rather than just the filename. That way, you can be sure where the file went, and not have to search for it everywhere. If you are using Windows, the output file might be somewhere in system32. But I could be wrong.
As others have said, the working directory is likely incorrect.
If you create a shortcut to the .exe, you can set the working directory in the shortcut properties. Right-click on the shortcut, select "Properties", and change the "Start in" property.
Of course a better answer is to put the full path of the file into the filename string when you open it.
It might be that Windows uses backslash, so try "\tmp" instead of "/tmp".
Also if all your files are in the same directory, then you can use find & replace and replace open(" with open("c:\\your_directory_here\

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