Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

scottypeps

macrumors newbie
Original poster
Feb 24, 2010
10
0
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.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
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
 

lloyddean

macrumors 65816
May 10, 2009
1,047
19
Des Moines, WA
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;
    }
 

scottypeps

macrumors newbie
Original poster
Feb 24, 2010
10
0
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!
 

scottypeps

macrumors newbie
Original poster
Feb 24, 2010
10
0
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.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,740
8,415
A sea of green
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)
 

lloyddean

macrumors 65816
May 10, 2009
1,047
19
Des Moines, WA
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;
    }
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
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
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.