0

I want to do a program in C++ that, when is executed (from anywhere), modifies a text file in a very specific path (and always the same one). To do so, I've defined the following function in C++:

void ChangeCourse(string course)
{
    ofstream active_course;
    active_course.open("~/.universidad/curso_activo.txt");

    if (!curso_activo)
        cout << "Error: cant't open the file" << endl;
    else
    {
        active_course << course;
        curso_activo.close();
    }
}

When executing the program that calls the function, I get the message Error: cant't open the file and, indeed, no file is created.

How do I have to define the path of the file such a way the program could read it and find it, regardless of where the program was called.

Note that I'm running the program in macOS.

Hope I've explained my self and thank you in advance.

  • 2
    This doesn't address the question, but get in the habit of initializing objects with meaningful values rather than default-initializing them and immediately overwriting the default values. In this case, that means changing `ofstream active_course; active_course.open("~/.universidad/curso_activo.txt");` to `ofstream active_course("~/.universidad/curso_activo.txt");`. Also, you don't have to call `active_course.close();`; the destructor will do that. – Pete Becker Oct 26 '21 at 19:14
  • You may want to look at this: https://stackoverflow.com/questions/33544123/c-paths-beginning-with – jjramsey Oct 26 '21 at 19:20
  • 2
    Could it be that the `~` is not being resolved? `ofstream` docs say: `filename - A string representing the name of the file to be opened. Specifics about its format and validity depend on the library implementation and running environment.` – Jim Rhodes Oct 26 '21 at 19:20

4 Answers4

4

~ is expanded (to your home directory) by the shell (that is to say, by the command line interpreter). It is not part of the *nix API per-se. (macOS is based on BSD Unix.)

Instead, you can expand the HOME environment variable with getenv() and append the rest of your path (including the filename) to that before opening it.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • Sorry, could you give an example to how to use the `getenv()` function and append it to another string. I'm trying it but I'm getting an error. – Mario Vago Marzal Oct 27 '21 at 09:18
  • Please add what you tried to your question (or, better probably, ask another question focussed on that). We don't baby people here. – Paul Sanders Oct 27 '21 at 21:33
1

You cant use ~/. to refer to the home directory of the user like you can do in the command shell.

You need to specify the full path, for example /home/zjanny/test.txt

zJanny
  • 21
  • 1
  • 1
    Better to [retrieve it from the OS](https://stackoverflow.com/questions/3020187/) at runtime, don't hard-code it. – Remy Lebeau Oct 26 '21 at 19:57
1

In C++17 you can use the filesystem library and hard code the path, if this is what you really want to do.

#include <filesystem>
#include <fstream>

namespace fs=std::filesystem;

int main() {

  fs::path p = "your-absolute-path-goes-here"; // 
  if(fs::exists(p)) {
    std::ofstream file(p);
    file << "Hello world!" << "\n";
  }
  return 0;  
}
AngelosFr
  • 115
  • 1
  • 9
  • Why is this the accepted answer? Hard coding an absolute path is not the same as expanding `~` to the current user's home directory at runtime. – Paul Sanders Oct 27 '21 at 21:31
0

Unless the file/folder you are looking for is in the current directory that the program is run from, you have to pass in the absolute file path.

In macOS you should be able to select the file you want to open and hit cmd+i to find the absolute path to a file.

frisco
  • 27
  • 3