Pass stream by reference
我想通过引用传递流,这是一个指针。 所以我将它作为指针传递给指针。 有人可以验证我的代码吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| int main (int argc , char** argv )
{
FILE *stream ;
printf("LINES: %d
",scan (stream ));
}
int scan (FILE *(*stream ))
{
stream = fopen("names.txt","r");
int ch = 0, lines =0;
while (!feof(*stream ))
{
ch = fgetc(*stream );
if (ch == '
')
{
lines ++;
}
}
fclose(*stream );
return lines ;
} |
没有收到输出。
-
同时,FEOF文件 - 是 - 总是错的
-
有人可以验证我的代码吗? 编译器将验证您的代码。
-
@ user3386109没错。 我有测试,它的工作原理。
-
@MOehm我做了编译,因此我声明没有收到输出。 我在学习。
-
似乎有效,但不是因为你相信的原因。 正确的代码与错误原因的代码之间存在差异。 while ( (ch = fgetc(*stream)) != EOF )是编写while循环的正确方法。
-
@ user3386109正如我提到的我正在学习,我从Dominic Rodger在页面链接上给出的答案中选择了这种格式
-
啊,但注意代码中的所有美元符号。 这不是C代码,它是PHP。 检查问题中的标签。
-
@ user3386109我会尽量小心。 你能帮我解决另一个问题请联系
您的代码存在设计问题。你到底想要达到什么目的?
如果您只想计算行数,请将FILE *本地化为您的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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 == '
') lines ++;
}
fclose(stream );
return lines ;
} |
如果要对已经使用fopen打开的文件执行常规文件操作(读取,写入,搜索,回放等),只需将句柄作为FILE *传递:
1 2 3 4 5 6 7 8 9 10
| int fget_non_space (FILE *stream )
{
int c ;
do {
c = fgetc(stream );
} while (isspace(c ));
return c ;
} |
在这种情况下,在此函数之外调用fopen和fclose。 (您不应该在程序中调用fclose,即使操作系统确保在退出后自动关闭文件,也应如此。)
将指针传递给文件句柄FILE **只有在想要在函数中更改该文件句柄本身时才有意义,例如通过调用fopen:
1 2 3 4 5
| int fopen_to_read (FILE **FILE pstream , const char *fn )
{
*pstream = fopen(fn ,"r");
return (*pstream != NULL ) ? 0 : -1;
} |
即使这样,最好还是返回文件句柄,如fopen那样。
您的示例代码会在main中保留打开的文件句柄,但您不会对其执行任何操作,甚至不会将其关闭。那是你要的吗?我对此表示怀疑。
-
非常感谢您的详细解释。它帮助我理解了整个逻辑/概念。但简单地说,我想通过引用传递'stream'。我忘了关闭文件(道歉),我已经纠正了问题中的原始代码。
-
是的,但是您知道在您的示例中,传递文件指针没有任何意义,因为它永远不会在scan之外使用。这种设计甚至是危险的,因为在调用scan之前,stream是未初始化的,而在callig scan之后,它指的是一个关闭文件。但是,在两种情况下都可以访问stream,它无效。正确的设计是"封装"文件句柄并将其范围限制在其使用范围内。
-
我会努力学习更好。我很难学习C,但我试图理解。你能帮我解决另一个问题链接
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| 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 == '
')
{
lines ++;
}
}
fclose(*stream ); // Close the FILE stream after use
return lines ;
}
int main (void)
{
FILE *stream ;
printf("LINES: %d
",scan (&stream )); //Pass address of `stream`. The address is of type `FILE**`
} |
-
是的,但如果你不在函数外部使用创建的句柄,那么将指针传递给文件句柄有什么用?你(和OP)也应该'fclose´文件。
-
while ( (ch = fgetc(*stream)) != EOF )
-
@ user3386109,编辑过。谢谢!
-
@MOehm,也许OP有一些要求。谢谢你提醒我fclose。我添加了它。
-
@CoolGuy:是的,当然,可能有一个我们不知道的特殊要求。既然OP已经插入了fclose,很明显只是误解了从外部传递指针的内容是什么。你的答案回答了这个问题,但在我看来,问题首先是一个错误的问题。没关系。
更换
1
| stream = fopen("names.txt","r"); |
同
1
| *stream = fopen("names.txt","r"); |
也
1 2
| printf("LINES: %d
",scan (stream )); |
同
1 2
| printf("LINES: %d
",scan (&stream )); |
-
@ user3386109你想详细说明吗?
-
@Vagish另外,你能解释我怎么能按值传递流?