关于C#:通过引用传递流

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;
}

没有收到输出。


您的代码存在设计问题。你到底想要达到什么目的?

如果您只想计算行数,请将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;
}

在这种情况下,在此函数之外调用fopenfclose。 (您不应该在程序中调用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中保留打开的文件句柄,但您不会对其执行任何操作,甚至不会将其关闭。那是你要的吗?我对此表示怀疑。


使用

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**`
}


更换

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));