通过引用传递流
Pass stream by reference
我想通过引用传递流,它是一个指针。所以我将它作为指向指针的指针传递。有人可以验证我的代码吗?
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;
}
没有收到输出。
替换
stream = fopen("names.txt", "r");
和
*stream = fopen("names.txt", "r");
还有
printf("LINES: %d\n",scan(stream));
和
printf("LINES: %d\n",scan(&stream));
使用
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**`
}
您的代码存在设计问题。你到底想达到什么目的?
如果您只想计算行数,请将 FILE *
设置为函数的局部值:
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;
}
如果您想对已使用 fopen
打开的文件执行常规文件操作(读、写、查找、倒带等),只需将句柄作为 FILE *
传递:
int fget_non_space(FILE *stream)
{
int c;
do {
c = fgetc(stream);
} while (isspace(c));
return c;
}
在这种情况下,fopen
和 fclose
都在该函数外调用。 (你不会在你的程序中调用 fclose
,你应该这样做,即使操作系统确保在退出后自动关闭文件。)
传递一个指向文件句柄的指针,FILE **
,只有当你想在函数中改变文件句柄本身时才有意义,例如通过调用 fopen
:
int fopen_to_read(FILE **FILE pstream, const char *fn)
{
*pstream = fopen(fn, "r");
return (*pstream != NULL) ? 0 : -1;
}
即便如此,最好 return 文件句柄,就像 fopen
那样。
您的示例代码使打开的文件句柄可在 main
中访问,但您不对其进行任何操作,甚至不关闭它。那是你要的吗?我怀疑。
我想通过引用传递流,它是一个指针。所以我将它作为指向指针的指针传递。有人可以验证我的代码吗?
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;
}
没有收到输出。
替换
stream = fopen("names.txt", "r");
和
*stream = fopen("names.txt", "r");
还有
printf("LINES: %d\n",scan(stream));
和
printf("LINES: %d\n",scan(&stream));
使用
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**`
}
您的代码存在设计问题。你到底想达到什么目的?
如果您只想计算行数,请将 FILE *
设置为函数的局部值:
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;
}
如果您想对已使用 fopen
打开的文件执行常规文件操作(读、写、查找、倒带等),只需将句柄作为 FILE *
传递:
int fget_non_space(FILE *stream)
{
int c;
do {
c = fgetc(stream);
} while (isspace(c));
return c;
}
在这种情况下,fopen
和 fclose
都在该函数外调用。 (你不会在你的程序中调用 fclose
,你应该这样做,即使操作系统确保在退出后自动关闭文件。)
传递一个指向文件句柄的指针,FILE **
,只有当你想在函数中改变文件句柄本身时才有意义,例如通过调用 fopen
:
int fopen_to_read(FILE **FILE pstream, const char *fn)
{
*pstream = fopen(fn, "r");
return (*pstream != NULL) ? 0 : -1;
}
即便如此,最好 return 文件句柄,就像 fopen
那样。
您的示例代码使打开的文件句柄可在 main
中访问,但您不对其进行任何操作,甚至不关闭它。那是你要的吗?我怀疑。