How to write to a file including directory name in C?

H

Hongyu

Dear all:

I am trying to write to a file with full directory name and file name
specified (./outdir/mytestout.txt where . is the current directory) in
C programming language and under Unix, but got errors of Failed to
open file ./outdir/mytestout.txt. Below is the code:

#include <stdio.h>

int main(void)
{
FILE *fp;
char fname[30];
char pathname[30];

strcpy(fname,"./outdir/mytestout.txt");
fp=fopen(fname, "w");
if (fp == NULL)
{
printf("Failed to open file %s\n", fname);
}
else
{
fprintf(fp, "This is just a test only");
}

fclose;

return 0;

}

I also try to write filename and directory with ,".\outdir
\mytestout.txt", or ,".//outdir//mytestout.txt" or ",".\\outdir\
\mytestout.txt", or even ,".///outdir///mytestout.txt" etc, and I also
tried to specify the whole directory with the current directory .
(dot) replaced by the real directory name, but all failed. I searched
on the internet and only found one relevant that said to specify
filename with full path, but how to specify full path in C under Unix?
Please help me.

Thanks for the help in advance.

Hongyu
 
H

Hongyu

Dear all:

I am trying to write to a file with full directory name and file name
specified (./outdir/mytestout.txt where . is the current directory) in
C programming language and under Unix, but got errors of Failed to
open file ./outdir/mytestout.txt. Below is the code:

#include <stdio.h>

int main(void)
{
   FILE *fp;
   char fname[30];
   char pathname[30];

   strcpy(fname,"./outdir/mytestout.txt");
   fp=fopen(fname, "w");
   if (fp == NULL)
   {
      printf("Failed to open file %s\n", fname);
   }
   else
   {
      fprintf(fp, "This is just a test only");
   }

   fclose;

   return 0;

}

I also try to write filename and directory with ,".\outdir
\mytestout.txt", or ,".//outdir//mytestout.txt" or ",".\\outdir\
\mytestout.txt", or even ,".///outdir///mytestout.txt" etc, and I also
tried to specify the whole directory with the current directory .
(dot) replaced by the real directory name, but all failed. I searched
on the internet and only found one relevant that said to specify
filename with full path, but how to specify full path in C under Unix?
Please help me.

Thanks for the help in advance.

Hongyu

One more information. Actually, my code in the line of fclose has been
corrected as fclose(fp), but I still got error of "Failed to open
file ./outdir/mytestout.txt
Segmentation fault."
 
H

Hongyu

Hongyu said:
I am trying to write to a file with full directory name and file name
specified (./outdir/mytestout.txt where . is the current directory) in
C programming language and under Unix, [..]

Try or any of the numerous Unix newsgroups.  Generally,
relative paths should be avoided.

V

Thanks. I will try that.
 
J

Jim Langston

Hongyu said:
I am trying to write to a file with full directory name and file name
specified (./outdir/mytestout.txt where . is the current directory) in
C programming language and under Unix, [..]

Try or any of the numerous Unix newsgroups. Generally,
relative paths should be avoided.

V

Thanks. I will try that.
 
J

James Kanze

Hongyu said:
I am trying to write to a file with full directory name and
file name specified (./outdir/mytestout.txt where . is the
current directory) in C programming language and under Unix,
[..]
Try news:comp.lang.c or any of the numerous Unix newsgroups.

Whether Unix or Windows (or C or C++), he might start by
ensuring that the directories exist. If there's no directory
outdir in the current directory, his fopen is going to fail.
(Of course, if he wants to create the directory, he'll have to
ask in the OS group, because there's no way to create a
directory portably.)
Generally, relative paths should be avoided.

Just curious, but why? I tend to prefer relative paths to
absolute for most things. Obviously, it all depends on what
you're doing, but would you like it if your compiler put the
object files in some absolute path?
 
J

Juha Nieminen

Hongyu said:
strcpy(fname,"./outdir/mytestout.txt");
fp=fopen(fname, "w");

The "./" part is not necessary (and I don't even know if it's
portable). Separating directories with '/' should be rather portable (at
least it works in windows as well as unix, although I don't really know
if it's standard).

You should really use the perror() to print the proper error message
in a case like this. It can be much more informative than just a "failed
to open" generic message. It can be used like this:

if(fp == NULL)
{
fprintf(stderr, "Failed to open file ");
perror(fname);
}

From the many possibilities for the error to happen, two are most likely:

1) The directory 'outdir' doesn't exist in the current directory.
fopen() will not create it if it doesn't exist.

2) You don't have write permissions to that directory.
 
J

James Kanze

James said:
[..]
Generally, relative paths should be avoided.
Just curious, but why? I tend to prefer relative paths to
absolute for most things. Obviously, it all depends on what
you're doing, but would you like it if your compiler put the
object files in some absolute path?
Well, I've seen programs that had problems that can be
distilled to
set_current_directory(somepath);
some_3rd_party_function();
// assume current directory is still 'somepath'
open_file(relativepath);
You cannot imagine the surprise on the faces of the developer
who wrote that code when he finds out that in a patched
version of the 3rd party library the current directory is
changed to something else, which is not documented and not
reported in the release notes.

There's only so much you can (or should) do to fight stupidity.
And libraries that change the current directory without
resetting it fall into that category. If you really can't avoid
using the library, you should at least wrap it, saving the
current directory when you call it, and restoring it when you
return. (To repeat my question: would you like it if your
compiler used this library, and ended up putting the generated
object files where ever the library went to.)
In such case you cannot go wrong with
some_3rd_party_function();
open_file(make_absolute_path(somepath, relativepath));

Provided you can obtain an absolute path. But it sounds like
two wrongs trying to make a right to me.
 
J

James Kanze

The "./" part is not necessary (and I don't even know if it's
portable).

In certain contexts (not here), at least under Unix, the "./"
has the effect of turning off searching in a path. (dlopen
comes to mind.) Thus, some programmers get used to using it,
and it doesn't hurt.
Separating directories with '/' should be rather portable (at
least it works in windows as well as unix, although I don't
really know if it's standard).

It's standard... Posix. The C++ standard doesn't even
guarantee directories.
You should really use the perror() to print the proper error
message in a case like this. It can be much more informative
than just a "failed to open" generic message.

I would prefer stderror. It gives you more options with regards
to formatting.
It can be used like this:
if(fp == NULL)
{
fprintf(stderr, "Failed to open file ");

Except that if there is a problem with this fprint, the errno
used by perror after it will not reflect the original problem.
I'd use something like:

int errorCode = errno ;
std::cerr << "Could not open " << fname << ", error was: "
<< stderror( errorCode ) << std::endl ;

(In C:
int errorCode = errno ;
fprintf( "Could not open %s, error was: %s\n",
fname, stderror( errorCode ) ) ;
. But frankly, I'd prefer to avoid it.)
perror(fname);
}
From the many possibilities for the error to happen, two are most likely:
1) The directory 'outdir' doesn't exist in the current directory.
fopen() will not create it if it doesn't exist.
2) You don't have write permissions to that directory.

3) A file with the same name already exists, and you don't have
access rights to it.

4) There are no more inodes left on the device. (I've been hit
by that one a couple of times recently.)

etc., etc.
 
G

Gennaro Prota

James Kanze wrote:
[...]
There's only so much you can (or should) do to fight stupidity.
And libraries that change the current directory without
resetting it fall into that category.

Not exactly on-topic, but this reminds me of one of those sentences
you can often see in mail and Usenet signatures:

It is impossible to make anything foolproof because fools are
so ingenious.

In the case above, anyway, it's hard to discern stupidity from
incompetence... touching a global entity without restore...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top