Opening a file of user's choice

P

phaedrus

Hi all,

I can't figure out what's wrong with this piece of code. It generates
a segmentation fault. The only thing I can think of is that fopen()
doesn't like a variable being used in place of a file name. Here's the
code which I've heavily commented so you can see what it's SUPPOSED to
do:

#include <stdio.h>

int main(void)
{
FILE *fp;
int c;
int b=0;
char s[25]; //declare array 's' to hold the filename

printf("Enter local filename: ");
fgets(s,24,stdin); //read string from keyboard into
array 's'


fp = fopen(s , "r"); //open the file referenced by
's' in read-mode.

while((c = fgetc(fp)) != EOF)
{
b++; //count number of characters in the file
}

fclose(fp);

printf("The number of characters in %s is:%d " ,s,b); //print out
total number of chars.


return 0;

}

Any suggestions would be welcome!
 
B

Ben Bacarisse

phaedrus said:
Hi all,

I can't figure out what's wrong with this piece of code. It generates
a segmentation fault. The only thing I can think of is that fopen()
doesn't like a variable being used in place of a file name. Here's the
code which I've heavily commented so you can see what it's SUPPOSED to
do:

#include <stdio.h>

int main(void)
{
FILE *fp;
int c;
int b=0;
char s[25]; //declare array 's' to hold the filename

printf("Enter local filename: ");
fgets(s,24,stdin); //read string from keyboard into array 's'

fp = fopen(s , "r"); //open the file referenced by 's' in read-mode.

while((c = fgetc(fp)) != EOF)
{
b++; //count number of characters in the file
}

fclose(fp);

// print out total number of chars.
printf("The number of characters in %s is:%d " ,s,b);

return 0;
}

Any suggestions would be welcome!

(a) fgets leaves the newline in the buffer. Your file will not have a
newline in its name.
(b) use // comments in posts only if you know how to stop the line
from wrapping! /* ... */ work much better in this environment.
(c) You don't need to use 25 and 24. fgets takes the real size of the
array so you can write fgets(s, sizeof s, stdin);
(d) Always check the success or failure of input functions.
 
P

phaedrus

Whoah! That was fast, Ben, thanks!
(a) fgets leaves the newline in the buffer.  Your file will not have a
newline in its name.
(b) use // comments in posts only if you know how to stop the line
from wrapping!  /* ... */ work much better in this environment.
(c) You don't need to use 25 and 24.  fgets takes the real size of the
array so you can write fgets(s, sizeof s, stdin);
(d) Always check the success or failure of input functions.
 
P

phaedrus

fflush(stdout);



     if (fp == NULL) {
         fprintf(stderr,
             "\nfopen() problem with \"%s\"\n", s);
     }

/*
** Maybe there's a newline character in your string?

Yeah, that'll be it alright. Btw, I read someplace that the use of
fflush() is not recommended. Can't recall why, but the author said
this custom function does a better job:

void dump_line( FILE * fp )
{
int ch;

while( (ch = fgetc(fp)) != EOF && ch != '\n' )
;
}

Any observations?
 
B

Ben Bacarisse

phaedrus said:
Yeah, that'll be it alright. Btw, I read someplace that the use of
fflush() is not recommended. Can't recall why, but the author said
this custom function does a better job:

void dump_line( FILE * fp )
{
int ch;

while( (ch = fgetc(fp)) != EOF && ch != '\n' )
;
}

Any observations?

The above is a portable function close to (but not exactly like) the
behaviour of fflush(stdin) on some systems. fflush(stdout) is quite
different and is well-defined. It flushed any buffered *output* so
that you can be sure your prompt is seen.
 
P

phaedrus

The above is a portable function close to (but not exactly like) the
behaviour of fflush(stdin) on some systems.  fflush(stdout) is quite
different and is well-defined.  It flushed any buffered *output* so
that you can be sure your prompt is seen.
Thanks for your tips, Ben.
I've tracked down the caveat I read elsewhere. It comes from an item
called 'most common C programming errors' and I'll give the relevant
snippet here:

"One incorrect solution is to use the following:

fflush(stdin);

This will compile but its behavior is undefined by the ANSI C
standard. The fflush() function is only meant to be used on streams
open for output, not input. This method does seem to work with some C
compilers, but is completely unportable! Thus, it should not be used."

Do you think this guy's concerns are justified?

thanks again.
 
B

Ben Bacarisse

phaedrus said:
Thanks for your tips, Ben.
I've tracked down the caveat I read elsewhere. It comes from an item
called 'most common C programming errors' and I'll give the relevant
snippet here:

"One incorrect solution is to use the following:

fflush(stdin);

This will compile but its behavior is undefined by the ANSI C
standard. The fflush() function is only meant to be used on streams
open for output, not input. This method does seem to work with some C
compilers, but is completely unportable! Thus, it should not be used."

Do you think this guy's concerns are justified?

Yes. I had intended my reply to suggest this but I can see that maybe
it is a bit weak: fflush(stdin) is undefined and could cause anything
at all to happen. Don't use it.
 
P

phaedrus

Yes.  I had intended my reply to suggest this but I can see that maybe
it is a bit weak: fflush(stdin) is undefined and could cause anything
at all to happen.  Don't use it.

Thanks for the clarification, Ben.
 
P

phaedrus

Actually I don't understand how this function works as it stands:

void dump_line( FILE * fp )
{
int ch;

while( (ch = fgetc(fp)) != EOF && ch != '\n' )
;

}

Surely this should be done within a do-while loop rather than a
while?
Unless I'm nuts (could well be) it just keeps fetching characters from
the input buffer until it encounters a '\n' whereupon it exits and
passes control back to main, leaving the '\n' sitting at the front of
the buffer.
 
W

Willem

phaedrus wrote:
) Actually I don't understand how this function works as it stands:
)
) void dump_line( FILE * fp )
) {
) int ch;
)
) while( (ch = fgetc(fp)) != EOF && ch != '\n' )
) ;
)
) }
)
) Surely this should be done within a do-while loop rather than a
) while?
) Unless I'm nuts (could well be) it just keeps fetching characters from
) the input buffer until it encounters a '\n' whereupon it exits and
) passes control back to main, leaving the '\n' sitting at the front of
) the buffer.

Was Pascal your first language, by any chance ?

It keeps reading characters until the character it has read is a '\n'.
That character has been read, so it's not at the front of the buffer
anymore.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
P

phaedrus

Was Pascal your first language, by any chance ?

ASM actually. :)
It keeps reading characters until the character it has read is a '\n'.
That character has been read, so it's not at the front of the buffer
anymore.

Aha! Of course. Thanks for putting me straight.
 
K

Keith Thompson

Ben Bacarisse said:
The above is a portable function close to (but not exactly like) the
behaviour of fflush(stdin) on some systems. fflush(stdout) is quite
different and is well-defined. It flushed any buffered *output* so
that you can be sure your prompt is seen.

I don't think that the behavior of fflush(stdin) on systems that
support it is particularly close to the above.

The dump_line function skips all input characters up to and including
the end of the line. fflush(stdin) on at least one system discards
any buffered input characters that haven't yet been read by fgetc() or
equivalent, regardless of line endings. Either can be useful in some
circumstances.

In general, of course, fflush(stdin)'s behavior is undefined.
 

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,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top