Solved

C++ function for file path

Posted on 2014-04-26
13
1,153 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
ID: 40025199
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:bbao
ID: 40025235
@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
ID: 40025247
>>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
Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

 
LVL 8

Expert Comment

by:Subrat (C++ windows/Linux)
ID: 40025670
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
ID: 40025870
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
ID: 40025881
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
 
LVL 28

Expert Comment

by:pepr
ID: 40026233
@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:bbao
ID: 40026286
> @userTester: You should write a bit more what is the goal.

+1
0
 
LVL 33

Assisted Solution

by:sarabande
sarabande earned 250 total points
ID: 40027770
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
ID: 40030577
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
ID: 40030637
>> 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
ID: 40040492
Thanks.
0
 

Author Closing Comment

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

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
Computer science students often experience many of the same frustrations when going through their engineering courses. This article presents seven tips I found useful when completing a bachelors and masters degree in computing which I believe may he…
This video teaches viewers about errors in exception handling.
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

808 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