Solved

C++ function for file path

Posted on 2014-04-26
13
1,104 Views
Last Modified: 2014-05-04
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
Comment
Question by:userTester
  • 4
  • 4
  • 2
  • +3
13 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
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
 
LVL 37

Expert Comment

by:Bing CISM / CISSP
Comment Utility
@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
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>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
 
LVL 8

Expert Comment

by:Subrat (C++ windows/Linux)
Comment Utility
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
 

Author Comment

by:userTester
Comment Utility
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
 
LVL 86

Expert Comment

by:jkr
Comment Utility
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
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 28

Expert Comment

by:pepr
Comment Utility
@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
 
LVL 37

Expert Comment

by:Bing CISM / CISSP
Comment Utility
> @userTester: You should write a bit more what is the goal.

+1
0
 
LVL 32

Assisted Solution

by:sarabande
sarabande earned 250 total points
Comment Utility
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
 

Author Comment

by:userTester
Comment Utility
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
 
LVL 86

Accepted Solution

by:
jkr earned 250 total points
Comment Utility
>> 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
 

Author Comment

by:userTester
Comment Utility
Thanks.
0
 

Author Closing Comment

by:userTester
Comment Utility
Thanks for providing some code, its a good way to demonstrate what you're saying.
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Does the idea of dealing with bits scare or confuse you? Does it seem like a waste of time in an age where we all have terabytes of storage? If so, you're missing out on one of the core tools in every professional programmer's toolbox. Learn how to …
This is about my first experience with programming Arduino.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now