ofstream directory problem

Discussion in 'Mac Programming' started by scottypeps, Feb 24, 2010.

  1. scottypeps macrumors newbie

    Joined:
    Feb 24, 2010
    #1
    I am having a problem when trying to specify a directory to put my txt file containing the output data.

    Code:
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main()
    {
      ofstream logfile;
      logfile.open ("log.txt", ios::out);
    
     if (!logfile){
          cout << "Error" <<endl;
          return 1;
     }
    for ( i=0; i<5; i++ ) {
    
        cout << "the robot is at location (" << x << "," << y << ")" << endl;
        cout << "which way should roomba move (enter F,B,L,R or Q)? ";
        cin  >> c;
    
        logfile << "You entered " << c << endl;
    
        if (( c=='F' ) || ( c == 'f' )){
          y = y + 1;
        }
        else if (( c=='B') || ( c == 'b' )) {
          y = y - 1;
        }
        else if (( c=='L') || ( c == 'l' )) {
          x = x - 1;
        }
        else if (( c=='R') || ( c == 'r' )) {
          x = x + 1;
        }
        else if (( c=='Q' ) || ( c == 'q' )) {
          q = true;
        }
        else {
          cout << "Oops! you entered something invalid. please try again" << endl;
         }
      } 
    logfile.close();
    return(0);
    }
    Now this works, but it puts the log.txt into my home directory instead of the program directory. When I change the ofstream to put it somewhere else, such as:
    logfile.open ("~/Desktop/log.txt", ios::eek:ut);

    it gives me an error. I've tried changing the permissions for the C++ file but that produces the error message as well. Any help would be appreciated.

    Thanks.
     
  2. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    Shell shortcuts like ~, ~myusername, etc. will not be expanded. You can use .. and other relative paths to access directories relative to the working directory, and absolute paths starting with /, but no ~. You may be able to build up a path using environment variables, etc. but it may not work cross-platform.

    -Lee
     
  3. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #3
    Code:
    string get_home_pathname()
    {
        return getenv("HOME");
    }
    
    int main()
    {
        string      strHomePathname = get_home_pathname() + "/log.txt";
        ofstream    logfile(strHomePathname.c_str());
        if ( !logfile.is_open() )
        {
            cout << "Error" <<endl;
            return 1;
        }
    
     
  4. scottypeps thread starter macrumors newbie

    Joined:
    Feb 24, 2010
    #4
    Thanks for your responses, as I'm still at the beginner level I don't completely understand all the code that was sent but I have a better understanding of what went wrong. The above code works great, but I will have to research more to see exactly whats going on.

    Thanks again!
     
  5. scottypeps thread starter macrumors newbie

    Joined:
    Feb 24, 2010
    #5
    Does anyone know why it automatically creates the .txt in the main user directory rather than the program's directory? I know I'm new to this, but it seems like an awful lot of code just to have the program look for/create a file in a specific directory.
     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    Your program is creating files in the Working Directory:
    http://en.wikipedia.org/wiki/Working_directory

    http://en.wikipedia.org/wiki/Special:Search?search=working+directory&fulltext=Search

    You will need to understand this concept in order to make sense of what happens when you use Relative Pathnames:
    http://en.wikipedia.org/wiki/Relative_path

    If it seems like a lot of work to be doing it over and over, well, that's why people write reusable functions.

    Besides, most command-line tools don't have hard-wired pathnames for input and output files. They use command-line args for that, which are the parameters conventionally known as argc and argv of the main() function:
    http://en.wikipedia.org/wiki/Command-line_argument
    http://en.wikipedia.org/wiki/Main_function_(programming)
     
  7. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #7
    Both lee1210 and chown33 are trying to tell you that your executables "current working directory" will be dependent upon how it was started.

    If it was started from the command line then the "current working directory" will be either your "HOME" directory, if you didn't changes it using the "cd" command, or whatever you last set it to with your last use of the "cd" command, prior to starting your executable.

    If you start your executable from within Xcode you probably will want to set the executables "working directory" by selecting "Edit Active Executable <your project name>" from the "Project" menu. This will bring up a dialog allowing you to set up the runtime environment of your executable. Select the "General" tab near the top of the Dialog. Select the appropriate radio button in the group titled "Set the working directory to:"

    The following code if used will always place to the log file "next" to the executable and is only really useful for development purposes and should never be left in deployable code.

    Code:
    int main(int argc, char* argv[], char* envv[])
    {
        string      strExecutablePathname(argv[0]);
    
        string      strExecutablePath(strExecutablePathname);
        strExecutablePath.erase(strExecutablePath.find_last_of('/')+1, strExecutablePath.length());
    
        string      strExecutableName(strExecutablePathname);
        strExecutableName.erase(0, strExecutableName.find_last_of('/') + 1);
    
        string      strLogPathname(strExecutablePath + "log.txt");
    
        ofstream    logfile(strLogPathname.c_str());
        if ( !logfile.is_open() )
        {
            cout << "Error" <<endl;
    
            return EXIT_FAILURE;
        }
    
     
  8. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #8
    I am confident lloyddean's code works as advertised, and demonstrates some interesting constructs... with that said, often software on unix-like systems will be installed by an admin in an established, system-owned place. Often standard users won't be able to write here. Obviously for toy programs writing almost anywhere should be fine, but for something that is to be distributed a sane thing to do would be to default output (results) to the working directory, allowing a commandline argument to change this, as chown33 mentioned. For temporary/throwaway files there are functions to generate temporary filenames safely.

    -Lee
     

Share This Page