Saving file to application directory

Discussion in 'Mac Programming' started by orangezorki, Jun 11, 2014.

  1. orangezorki macrumors 6502a

    Aug 30, 2006
    Hello everyone,

    Firstly, I just wanted to say thank you again to all of you who have been helping me with the resurrection of my C programming. Your help has been invaluable and I have made great progress as a result.

    Along the way, I have realised that I don't need OOP for my project, so I have suck with C as I have used it in the past and it's less 'new' to learn for my goals.

    The one problem I have left is that I can't for the life of me work out how to save a file to the same folder as the command line app is run from. This is the code I am using so I can save a different file for each of the runs my app makes:

    void SaveToBinaryFile(void)
        FILE *Binfp = NULL;
        char binbuffer[32]; // The filename buffer.
        snprintf(binbuffer, sizeof(char) * 32, "FileD%iGen%i.dat", Max , CurrentG );
        Binfp = fopen(binbuffer, "a");
    At the moment, it saves to the same folder as the built program buried deep if the bowels of Xcode if I run it from Xcode, otherwise it just dumps into my user folder. I have tried to put a slash (either way) before the string but to no avail.

    Any ideas?

  2. subsonix macrumors 68040

    Feb 2, 2008
    You can try using getcwd which will allocate a path string. Check out the man page for getcwd. You could also add a return value to the function, so that the calling function can check if everything went well.
  3. orangezorki thread starter macrumors 6502a

    Aug 30, 2006
    Thanks - so is there a way I can combine the result of getcwd with the filename string I have created? Is it as simple as including it as %s ?

  4. subsonix macrumors 68040

    Feb 2, 2008
    You need to append them to a new string I guess. But what is it you are trying to do? If you only want to save a file to the current working directory of the application, then that's the default. So if you just open the file, it will be in the same directory as the application.
  5. chown33 macrumors 604

    Aug 9, 2009
    The problem is it's saving to the current working directory. Using cwd() won't change that. It will still be a directory deep inside of Xcode's built directories.

    The solution is to change the current working directory of the program when it's run, so the implicit use of the current working directory produces the desired results. There is usually a way to do this in Xcode, as part of the scheme or build, but the exact way to do it depends on which version of Xcode you're using.

    So please tell us what your Xcode version is.
  6. subsonix macrumors 68040

    Feb 2, 2008
    Yeah, I missed that he used Xcode.
  7. orangezorki thread starter macrumors 6502a

    Aug 30, 2006
  8. chown33 macrumors 604

    Aug 9, 2009
  9. orangezorki thread starter macrumors 6502a

    Aug 30, 2006
    Thank you - that will work perfectly for the moment. However, I must admit that I am surprised that there isn't just an easy one line way of saving to the same directory as the app is launched from...

  10. chown33 macrumors 604

    Aug 9, 2009
    I don't understand what you mean.

    It's rare that a command-line app, or a bundled Mac app, would need to write files to the directory where the app itself resides. In both cases, the user might not have permission to write to that directory. In the command-line case, /bin or /usr/bin, or a /local variant thereof, will often be root-writable only. In the bundled app case, apps usually run from /Applications or /Applications/Utilities, which are also dirs with restricted write.

    In the command-line case, the current working directory is already, well, the current working directory. That is, if you cd to ~/Documents, then that becomes the current working directory. A command that runs while you're in that directory with command-line parameters like "thisFile" or "thisDir/thatFile" will automatically (and implicitly) use the working directory, because the filenames themselves are relative to the working directory. If you cd to a different directory, then different pathnames would be in order.

    I'm not sure you understand what a working directory is, nor the difference between a relative pathname (i.e. one relative to the current working directory), and an absolute pathname. An absolute pathname is one that starts with "/", and it doesn't care what the working directory is, because the full absolute pathname isn't relative to the working directory.

    At this point, I don't know whether you're building a command-line app or a bundled app. My guess is a command-line one, but it'd be clearer if you stated what you're doing.

    If it's a command-line app, then please explain why it's necessary for this particular command (whatever it does) to write to the directory where the command itself resides.
  11. orangezorki thread starter macrumors 6502a

    Aug 30, 2006
    Sorry for the delay in replying.

    I do understand the difference between relative and absolute paths, as well as the concept of the current working directory. But I will admit to being very noobish in regard to the command line and programming.

    All I was saying is that my program is tiny (entire executable in the 10s of Kbytes), but produces immense amounts of data. I've now got it working, and after a few days, it has already generated about 3/4 of a TB of data. It would be great to just be able to put it on a large external drive, connect it to a computer, and have it save to the same drive automatically, and for me that seems to be a reasonable default behaviour.

  12. Catfish_Man macrumors 68030


    Sep 13, 2001
    Portland, OR
    The default behavior reflects the overwhelmingly common case. For applications, that's "there is no default case", and they're expected to use NSSavePanel. For command line utilities, the common case is that they're installed in /bin or similar, which is not writeable, so the default case is the current working directory.

    Removable drives with writeable directories containing a mix of binaries and user data is a very uncommon case indeed.
  13. chown33 macrumors 604

    Aug 9, 2009
    How would you typically run your program? Would you 'cd' into the directory on the external drive, and then type "./yourProgNameHere"? Or would you double-click the program on the external drive?

    If you explain how your program will typically be used, we can suggest a way for the program to find what directory it's running from and use it. Without that, we're left to either guess what you'll want to do, or dictate some constraints (which you may not like), or enumerate a somewhat lengthy list of possible strategies.

    The more specific you can be in describing exactly what you want to do and how you want to do it, the more specific a suggestion can be.

    A command-line program typically expects command-line args. Or it uses a default such as the current working directory. Another possibility is environment variables for things that don't change often. One can also use the 'defaults' system of named settable defaults (the NSUserDefaults class, and its CF companion) in a command-line tool.

    Those are some possible strategies. There are others. Any of those can be explained in more detail, but honestly, it's going to be a lot simpler if you describe how you want it to act, from a user's perspective.
  14. subsonix macrumors 68040

    Feb 2, 2008
    Since this is a command line tool, why not add the option to provide a path as argument when you start the application? Then you can use a different volume, or what ever you like.

Share This Page