"To many files open error <EMFILE>" bug

S

someone

I'm making an program that encodes text, and then writes it into
another text file. The problem is that I can't seem to get the "file
exists" checking right. If I use the command (coder is the
application):
coder something.txt an_exsiting_file.txt, then if I chose to overwrite
"an_exsiting_file.txt", an error message pops up, saying that to many
files are open <EMFILE>. Any help would be appreciated. Here is the
code (incomplete but still compilable):

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main(int argc, char *argv[])
{
FILE *text, *dest;
int ch;
if(argc!=3)
{
printf("Use as: coder <text file> <encoded file>");
exit(EXIT_FAILURE);
}
if((text=fopen(argv[1],"r"))==NULL)
{
perror(argv[1]);
exit(EXIT_FAILURE);
}
if((dest=fopen(argv[2],"r"))==NULL)
{
if(errno==ENOENT)
{
if((dest=fopen(argv[2],"w"))==NULL)
{
perror(argv[2]);
exit(EXIT_FAILURE);
}
}
else
{
perror(argv[2]);
exit(EXIT_FAILURE);
}
}
else
{
fflush(stdin);
printf("The file to be written to exsits. Are you want to overwrite
it [y/n]");
ch=getchar();
do{
if((ch=='y')||(ch=='Y'))
{
fflush(stdin);
if((dest=fopen(argv[2],"w"))==NULL)
{
perror(argv[2]);
exit(EXIT_FAILURE);
}
}
else if((ch=='n')||(ch=='N'))
{
fflush(stdin);
printf("Action Canceled");
exit(EXIT_FAILURE);
}
else
{
printf("Invalid character, Try again\n");
fflush(stdin);
}
}while(ch=='y' || ch=='Y' || ch=='n' || ch=='N');
}
putc('h',dest);
fclose(text);
fclose(dest);
return 0;
}

Sorry for the 8-space tabs, but I copyed directly from MVC++ 6.0, and I
don't think notepad will do any good.
 
E

Eric Sosman

someone said:
I'm making an program that encodes text, and then writes it into
another text file. The problem is that I can't seem to get the "file
exists" checking right. If I use the command (coder is the
application):
coder something.txt an_exsiting_file.txt, then if I chose to overwrite
"an_exsiting_file.txt", an error message pops up, saying that to many
files are open <EMFILE>. Any help would be appreciated. Here is the
code (incomplete but still compilable):

Your problem is with this construct:
ch=getchar();
do{
[...]
}while(ch=='y' || ch=='Y' || ch=='n' || ch=='N');

Observe that if you get a valid response (y/Y/n/N) the
loop repeats -- and since it doesn't read a new response, it
does the same thing it did before, and repeats, and does it
again, and repeats, and does it again ...

A few other points:

- fflush(stdin) has no meaning: You can only "flush" an
output stream. Try it on an input stream, and there's
no telling what might happen.

- On the other hand, you're missing an fflush(stdout)
call. If you want to be sure (or as sure as you can
be) that a prompt appears before you try to read the
response to it, fflush(stdout) after writing the prompt
and before reading the response.

- There's a laudable attempt to take different actions on
different error conditions. Unfortunately, C runs on a
wide variety of platforms whose file systems are not all
alike, and you cannot be sure that a given error condition
will produce a predictable Exxxxxx value. (In fact, you
cannot be sure that a failing fopen() will produce *any*
Exxxxxx value -- but most do.) Hence, all that part of
the logic is specific to particular platforms, and may not
work as intended on other machines.
 
S

someone

Thanks for the help, but now it says "Permission denied <EACCES>", any
idea on how to fix that?
 
E

Eric Sosman

someone said:
Thanks for the help, but now it says "Permission denied <EACCES>", any
idea on how to fix that?

Not in the context of platform-independent C, no.
The language doesn't define EACCES or what it means, so
you need to check your platform's documentation for hints
about what it's trying to tell you.

<off-topic>

It's *probably* trying to tell you that you lack the
appropriate permission for the kind of file access you're
attempting. Note that the permission failure might refer
to the target file itself, or to any of the directories
in its path -- and note that I've already said too much,
because C doesn't even have a notion of "directory."

</off-topic>
 
C

CBFalconer

someone said:
.... snip ...

Sorry for the 8-space tabs, but I copyed directly from MVC++ 6.0,
and I don't think notepad will do any good.

I am not willing to put up with them. All you had to do was
convert the tabs to a suitable number of spaces. If your editor
won't do it for you (most will) there are plenty of utilities
available for the job.

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
 
A

Andrew Poelstra

I'm making an program that encodes text, and then writes it into
another text file. The problem is that I can't seem to get the "file
exists" checking right. If I use the command (coder is the
application):
coder something.txt an_exsiting_file.txt, then if I chose to overwrite
"an_exsiting_file.txt", an error message pops up, saying that to many
files are open <EMFILE>. Any help would be appreciated. Here is the
code (incomplete but still compilable):

Wow, did your space key bite you?
1) Don't use tabs on Usenet.
2) Space out your expressions. I've fixed both problems for my own
readability (and others').
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main (int argc, char *argv[])
{
FILE *text, *dest;
int ch;
if(argc != 3)
{
printf("Use as: coder <text file> <encoded file>");

fputs (stderr, "Use as: coder input output");
exit(EXIT_FAILURE);
}
if ((text = fopen (argv[1], "r")) == NULL)
{
perror (argv[1]);

Just so you know, this function isn't guaranteed to be portable. If that's
a concern, you should replace it with a potentially less descriptive fputs()
message.

....
Sorry for the 8-space tabs, but I copyed directly from MVC++ 6.0, and I
don't think notepad will do any good.

Sure it will. Type <tab>, copy it, open the "search and replace" window,
paste it into the "original text" box, and put how ever many spaces you
want (usually 2-4) into the "replacement text" box. (Note: I paraprased
heavily in my quoted text.)


You need to work on your error handling and coding style:

#define REQ_ARGS = 3;
#define PERROR(str) fputs (stderr, str)

int main (int argc, char *argv[])
{
int error = 0;
FILE *f1 = NULL;
FILE *f2 = NULL;

if (argc == 3)
{
f1 = fopen (argv[1], "r");
f2 = fopen (argv[2], "w");

if (f1 == NULL)
PERROR ("Couldn't open input file.");

if (f2 == NULL)
PERROR ("Couldn't open output file.");

error = !(f1 && f2);
} else {
PERROR ("Usage: coder input output");
error = 1;
}

if (!error)
{
/* Rest of code here. */
}

return error ? EXIT_FAILURE : 0;
}

See how I pulled that off using minimum indentation and only one exit point?
Many people consider more than 3 tabs bad code; this isn't always possible,
but it's a good rule of thumb.
 
D

Dave Thompson

<OT>
Sure it will. Type <tab>, copy it, open the "search and replace" window,
paste it into the "original text" box, and put how ever many spaces you
want (usually 2-4) into the "replacement text" box. (Note: I paraprased
heavily in my quoted text.)
Or in MSVS6 itself just select all (ctrl+A) and Edit / Advanced /
Untabify Selection. And/or set the editor options (for each necessary
filetype) to use spaces rather than tabs for indentation.

- David.Thompson1 at worldnet.att.net
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top