fprintf - Unable to write text to file

George Collins's icon

Heya!

I am having issues writing text to files within my external. I am able to create a file, but unable to write into it:

FILE *theFile;
theFile = fopen(path, "w+");
fprintf(theFile, "hello world");
pclose(theFile);

I have tested the code in a normal xCode C executable project and it writes to the file fine, so I am assuming there isn't some I don't understand about using these functions within side Max.

I also tried using sysfile_writetextfile() as described in the MaxAPI document (p49) but also had the same issue of being able to create a file without writing to it.

Anyone able to suggest where I am going wrong?

Thanks in advance!

If its relevant... I am on Mac Catalina and Max definitely has file permissions as it is able to write using standard max objects.

Luigi Castelli's icon

Hi there,

generally you should be using the Max API calls for writing and reading files.
It is not recommended to directly call low-level C functions such as fopen() or pclose().

Download the source code of the [chuck~] object here.
https://chuck.cs.princeton.edu/release/

In one of its methods the [chuck~] object uses sysfile_writetextfile().
That should provide a good example on how to use the function.

Hope it helps.

- Luigi

George Collins's icon

Hey Luigi, thanks for your help again.

I followed that link and downloaded the source code but couldn't seem to find any source code for the chuck~ max object? However I did find it here. The source code appeared to be quite old and using some depreciated functions, and in 32bit, however by copying the functions I needed into my current project and changing the depreciated types/functions, I believe I resolved that.

Unfortunately though I still have the same problem of being able to create the file but not being able to write to it. My code including sysfile_writetextfile() looks like this:

char *buf = "write me into a file";
err = sysfile_writetextfile(fh, &buf, TEXT_LB_NATIVE);

All this does is create a file of zero bytes....

George

Luigi Castelli's icon

ok, I understand...
here is a more complete and "official" example that I found online.
Note that you have to defer the function that does the heavy lifting.

Also, from your example I am not sure how you get the file handle variable (fh)
I am assuming you have a valid handle, but - if not - your problem could also be related to that.

Lastly, I don't know if it's gonna make a difference or not, but remember to call sysfile_close() after sysfile_writetextfile()

Here we go...
void myobject_write(t_myobject *x, t_symbol *sym)
{
defer(x, (method)myobject_dowrite, sym, 0, NULL);
}

void myobject_dowrite(t_myobject *x, t_symbol *sym)
{
long filetype = 'TEXT';
long outtype;
short numtypes = 1;
char filename[MAX_FILENAME_CHARS];
short path;

if (sym == gensym("")) { // if no argument supplied, ask for file
if (saveasdialog_extended(filename, &path, &outtype, &filetype, 1)) {
return; // non-zero: user cancelled
}
} else {
strcpy(filename, sym->s_name);
path = path_getdefault();
}
myobject_writefile(x, filename, path);
}

void myobject_writefile(t_myobject *x, char *filename, short path)
{
char *buf = "write me into a file";
t_filehandle fh;
long err;

err = path_createsysfile(filename, path, 'TEXT', &fh);
if (err) {
return;
}
err = sysfile_writetextfile(fh, &buf, TEXT_LB_NATIVE);
sysfile_close(fh);
}

Let me know if this works for you...

- Luigi

George Collins's icon

Thanks Luigi, I've read up on the defer() in the API doc to understand more about this.

I tried the above and noticed whilst debugging that when the object was calling myobject_write, it wasn't calling myobject_dowrite in the defer function. I notice that in the documentation it says:

Defer execution of a function to the main thread if (and only if) your function is executing in the scheduler thread.

So having a further look, myobject_write is executing on the main thread already - not sure if this is an issue or not...

For the sake of thoroughness, I removed the defer function and just executed the myobject_dowrite in the myobject_write normally. But once again, it is creating the file but not writing anything into it.

Luigi Castelli's icon

The last thing that comes to mind would be the following:

char buf[256] = {0};
strncpy(buf, "write me into a file", 255);
err = sysfile_writetextfile(fh, &buf, TEXT_LB_NATIVE);

If that doesn't work, I am at the end of my rope...
There might be a bug in the function sysfile_writetextfile() or I just don't understand how to use it.

Sorry for not being able to provide more help.

- Luigi

George Collins's icon

Alas, afraid not.

Not to worry though, thank you for spending the time trying.

If I solve this I'll post on here just in case others have a similar issue...