Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1674
  • Last Modified:

C++ function for file path

I am new to C++, and I don't want to hard code a .txt file path, so is there a function that returns the path to the current .cpp file, which is found in the regular Source folder?

Thanks
0
userTester
Asked:
userTester
  • 4
  • 4
  • 2
  • +3
2 Solutions
 
jkrCommented:
There's be the macreo '__FILE__' that expands to the .cpp file name, but I guess that's not what you need. That would be eiter 'GetCurrentDirectory()' (http://msdn.microsoft.com/en-us/library/windows/desktop/aa364934(v=vs.85).aspx) on Windows or 'getcwd()' (http://man7.org/linux/man-pages/man2/getcwd.2.html) on UN*X-like systems.
0
 
bbaoIT ConsultantCommented:
@userTester

are you trying to run a binary executable to retreive the full path name of its C++ source code? that's impossible if you need a compiler and/or platform independent solution.

for Microsoft C++, if there is no DEBUG info added into the runtime, you still can't locate source code related informtion.

@jkr

GetCurrentDirectory() and getcwd() are for run time only, not for compiler time. therefore they wil return the current folder where the binary code was loaded and executed from the shell. it has nothing to do with the source code.
0
 
jkrCommented:
>>GetCurrentDirectory() and getcwd() are for run time only, not for compiler tim

Oh, really? That must have been why I started my comment with "There's be the macreo '__FILE__' that expands to the .cpp file name" ;o)
0
What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

 
Subrat (C++ windows/Linux)Software EngineerCommented:
You can use "GetFullPathName()" but I think file needs to be present in current working directory.

Indirectly what JKR is suggested is also acceptable.

If you want the path of source folder then you can use GetCurrentDirectory() which will return you the path of executable. Then you can manipulate the return path string like ../../Source or something similar.

Refer:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364963%28v=vs.85%29.aspx
0
 
userTesterAuthor Commented:
I would like to be able to open a text file, read the data, write to the text file etc, without having to hard code the path.
0
 
jkrCommented:
And the text file should reside in the same directory as your program? If so, you can use 'GetCurrentDirectory()' or 'getcwd()' as mentioned above. But, on most systems this path will be identical with the default path used for creating files.
0
 
peprCommented:
@userTester: You should write a bit more what is the goal. What problem do you want to solve? A better solution can be different than you anticipate.
0
 
bbaoIT ConsultantCommented:
> @userTester: You should write a bit more what is the goal.

+1
0
 
sarabandeCommented:
I would like to be able to open a text file, read the data, write to the text file etc, without having to hard code the path.
neither the source folder nor the bin folder where the exe file resides are a good place for a text file. the source file rarely is available at a non-developer machine and even if the program is a developer tool the source path may be different at an other pc if you are not the only one who uses the program. if the program is a developer tool you may use the project directory as default for the text file. in visual studio you would set the command setting at 'configuration properties - debugging' for debug configuration to .\debug\myapp.exe respectively to .\release\myapp.exe. the .\ means the current project folder (where the .vcxproj file resides). when you start the program by f5 the current directory will be the project folder and you can open the text file without any path.

int main()
{
      std::ifstream mytextfile("myapp.txt");
      if (!mytextfile) 
           return 2;   // file not found.

Open in new window


if you want to call the program from desktop icon, you would create a link that points to the project directory as start folder. if you start it from command window you would change to project directory and then start the program by  .\debug\myapp.exe. for all those alternatives the text file could be opened without any path.

if you have a setup program or want to start your program from everywhere without to care for the text file path, you could register your program in the registry and write the data path (and/or the program path) to the registry.

there are different ways to achieve that but the best probably is to add a "register mode" to your program:

int main(int nargs, char * szargs[])
{
      if (nargs == 4 && stricmp(szargs[1], "/register") == 0)
      {
            HKEY hkey = NULL;
            int r = RegCreateKey(HKEY_CURRENT_USER, "Software\\MyName\\MyApp", &hkey);
            if (r != ERROR_SUCCESS)
                  return r;
            r = RegSetValueEx(hkey, "Program Path", 0, 
                      REG_EXPAND_SZ, (BYTE*)szargs[2], strlen(szargs[2])+1);
            if (r != ERROR_SUCCESS)
                  return r;
              r = RegSetValueEx(hkey, "Data Path", 0, 
                      REG_EXPAND_SZ, (BYTE*)szargs[3], strlen(szargs[3])+1);
            if (r != ERROR_SUCCESS)
                  return r;
            RegCloseKey(hkey);
            return 0;
      }
      
      HKEY hkey = NULL;
      int r = RegOpenKey(HKEY_CURRENT_USER, "Software\\MyName\\MyApp", &hkey);
      if (r != ERROR_SUCCESS)
           return r;
      char szpath[MAX_PATH+1] = {  0 };
      DWORD siz = (DWORD)sizeof(szpath);
      r = RegGetValue(hkey, "Data Path", 0, NULL, (void*)szpath, &siz);
      if (r != ERROR_SUCCESS)
           return r;
      RegClose(hkey);
      szpath[siz] = '\0';
      strcat(szpath, "myapp.txt");
      std::ifstream mytextfile(szpath);
      if (!mytextfile) 
           return 2;   // file not found.

Open in new window


with the above code you once would register by

myapp /register "c:\projects\\myapp\\release" "c:\\projects\\myapp"

Open in new window


to start the program from everywhere by name only you would add the program path additionally to the Path environment variable in system settings - enhanced - environment variables.

Sara
0
 
userTesterAuthor Commented:
I haven't had the chance to test any of the suggestions, thus the delay on my side. I will go through the suggestions, and get back to you all. Thanks.

If you have very simple complete example code, that would help a stack.

There seems to be different suggestions for different scenarios, so what I would like to be able to do is have it working in a developer environment on MS Windows and Apple OS. So if I ran the code in Xcode and Visual Studio, I should be able to access the .txt file without hard-coding the path. You can also make suggestions on how the code would change when run as an application on either environment.

Thanks.
0
 
jkrCommented:
>> have it working in a developer environment on MS Windows and Apple OS

In that case, 'getcwd()' seems to be the way to go, since it is available on both (MS only prepends it with an underscore), e.g.

#ifdef _WIN32 // windows
#include <direct.h> // for '_getcwd()'
#define getcwd(x,y) _getcwd(x,y) // map name
#define PATHSEP '\\'
#else // OS X et. al.
#include <unistd.h>
#define PATHSEP '/'
#define MAX_PATH 2048
#endif
#include <stdio.h>

int main () {

  char* pMyFile = "test.txt";
  char* pCurDir = getcwd(NULL,0);
  char acFile[MAX_PATH];

  FILE* pFile;

  if (NULL == pCurDir) return -1; // failed, should not happen

  sprintf(acFileName,"%s%c%s;",pCurDir,PATHSEP,pMyFile);

  printf("Using '%s'\n", acFileName);

  pFile = fopen(acFileName,"w");

  fprintf(pFile,"Hello world!");

  fclose(pFile);
  free(pCurDir); // cleanup

  return 0;
}

Open in new window


Or, a "pure" C++ approach:

#ifdef _WIN32 // windows
#include <direct.h> // for '_getcwd()'
#define getcwd(x,y) _getcwd(x,y) // map name
#define PATHSEP '\\'
#else // OS X et. al.
#include <unistd.h>
#define PATHSEP '/'
#define MAX_PATH 2048
#endif
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;

int main () {

  string sMyFile = "test.txt";
  char* pCurDir = getcwd(NULL,0);

  if (NULL == pCurDir) return -1; // failed, should not happen

  string sFileName;
  ofstream os;

  ss << pCurDir << PATHSEP << sMyFile;

  sFileName = ss.str();

  cout << "Using '" << sFileName << "'" << endl;

  os.open(sFileName.c_str());

  os << Hello world!;

  free(pCurDir); // cleanup

  return 0;
}

Open in new window

0
 
userTesterAuthor Commented:
Thanks.
0
 
userTesterAuthor Commented:
Thanks for providing some code, its a good way to demonstrate what you're saying.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 4
  • 4
  • 2
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now