Solved

C++ function for file path

Posted on 2014-04-26
13
1,305 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

 
LVL 9

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 29

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 34

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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

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 article will inform Clients about common and important expectations from the freelancers (Experts) who are looking at your Gig.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

623 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