Reputation: 673
I am suppose to pass stream, which is a pointer, by reference. So I am passing this as a pointer to a pointer. Can someone please verify my code?
int main(int argc, char** argv)
{
FILE *stream;
printf("LINES: %d\n",scan(stream));
}
int scan(FILE *(*stream))
{
stream = fopen("names.txt", "r");
int ch = 0, lines=0;
while (!feof(*stream))
{
ch = fgetc(*stream);
if (ch == '\n')
{
lines++;
}
}
fclose(*stream);
return lines;
}
No output received.
Upvotes: 1
Views: 1427
Reputation: 20244
Use
int scan(FILE **stream) //no need for brackets
{
*stream = fopen("names.txt", "r"); //* is for dereferencing
if(*stream==NULL) // Checking the return value of fopen
{
printf("An error occured when opening 'names.txt'");
return -1;
}
int ch = 0, lines=0;
while ((ch = fgetc(*stream))!=EOF) //while(!feof) is wrong
{
if (ch == '\n')
{
lines++;
}
}
fclose(*stream); // Close the FILE stream after use
return lines;
}
int main(void)
{
FILE *stream;
printf("LINES: %d\n",scan(&stream)); //Pass address of `stream`. The address is of type `FILE**`
}
Upvotes: 2
Reputation: 29126
Your code has design issues. What exactly do you want to achieve?
If you just want to count the lines, make the FILE *
local to your function:
int count_lines(const char *filename)
{
FILE *stream = fopen(filename, "r");
int lines = 0;
while (1) {
int c = fgetc(stream);
if (c == EOF) break;
if (c == '\n') lines++;
}
fclose(stream);
return lines;
}
If you want to do a regular file operation (read, write, seek, rewind etc.) to a file that has already been opened with fopen
, just pass the handle as FILE *
:
int fget_non_space(FILE *stream)
{
int c;
do {
c = fgetc(stream);
} while (isspace(c));
return c;
}
In that case, both fopen
and fclose
are called outside this function. (You don't call fclose
in your program, which you should, even if the operating system makes sure to close the file automatically after exiting.)
Passing a pointer to the file handle, FILE **
, makes sense only if you want to change that file handle itself in the function, for example by calling fopen
:
int fopen_to_read(FILE **FILE pstream, const char *fn)
{
*pstream = fopen(fn, "r");
return (*pstream != NULL) ? 0 : -1;
}
Even then, it would be better to return the file handle, as fopen
does.
Your example code leaves the open filehandle accessible in main
, but you don't do anything with it, you don't even close it. Is that what you want? I doubt it.
Upvotes: 2
Reputation: 2547
Replace
stream = fopen("names.txt", "r");
with
*stream = fopen("names.txt", "r");
Also
printf("LINES: %d\n",scan(stream));
with
printf("LINES: %d\n",scan(&stream));
Upvotes: 1