使用 fstream 对象作为函数参数

11
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>

void vowel(fstream a){
    char ch;
    int ctr = 0;
    while(!a.eof()){
        a.get(ch);
        if (ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U'){
            cout << ch;
            ctr++;
        }
    }
    cout << "Number of Vowels: " << ctr;
}

main(){
    fstream a;
    a.open("temp.txt", ios::in);
    vowel(a);
return 0;
}

在这个简单的程序中,我试图计算文件temp.txt中大写元音字母的数量。然而,我遇到了错误:

在函数fstream::fstream(fstream&)中,ios::ios(ios &)不可访问

在函数本身中打开文件可以解决问题。为什么会这样呢? 非常感谢。

NB:

如何通过函数参数使用fstream(特别是ofstream)

这里说,它应该按照我尝试的方式工作。

Rick

3个回答

16

fstream对象不可复制。应改为通过引用传递:fstream&

void vowel(fstream& a)

请注意,您可以通过向构造函数提供相同的参数来避免调用open()

fstream a("temp.txt", ios::in);

不要使用while(!a.eof()),应该立即检查读操作的结果。只有在尝试读取文件中最后一个字符之后,eof()才会被设置。这意味着当上一次调用get(ch)从文件中读取了最后一个字符时,!a.eof()将为真,但是随后的get(ch)将失败并设置eof,但代码直到处理完ch后才会注意到读取失败。

正确结构示例:

while (a.get(ch)) {

谢谢解释。避免使用open()...我知道这个。谢谢。但是eof()有什么问题?应该用什么代替? - DragonClaw
太好了。这就是为什么当我尝试读取包含类并显示内容的文件时,我会两次获得最后一个输出的原因。 我已经找到了一个解决方法,通过在再次输出之前检查(a.eof()),而不是在while循环中检查它。 非常感谢hmjd。 - DragonClaw
@hmjd 我有点困惑。传递流还是字符串行更有效率? - Arpit
非常感谢这个。对于其他初学者:fstram&应该放在函数定义中,而不是在调用时。 - qubodup

4

你需要通过引用传递fstream

void vowel(fstream& a){ .... }
//                ^ here!

2
尝试这个。不要发送文件,而是计算每行中的元音字母数量。
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
int vowels=0;
void vowel(string a){
    char ch;
    int ctr = 0;
int temp=0;
    for(temp=0,temp<a.length();temp++){
        ch=a.at(temp);
        if (ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U'){
            cout << ch;
            ctr++;
        }
    }
    vowels+=ctr;
}

main(){
    fstream a;
    a.open("temp.txt", ios::in);

string temp;
while(getline(a,temp))
{
vowel(temp);
function2(temp);
function3(temp);


... so on for more then one functions.

}        
vowel(a);
    return 0;
    }

如果你想传递文件,请使用上述答案(通过引用传递 fstream)。


这也可以运行。但是我计划编写多个函数(计算元音字母的数量、计算单词数量、句子数量等等),并且不想在每个函数中打开文件。你的解决方案会让我为每个函数再次编写while(getline(a, string temp))循环。 - DragonClaw
1
你只需要打开文件一次!在循环内部调用其他函数。 - Arpit
但它会获取每一行并输出。 例如: 元音数量:5 [对于l1] 单词数量:2 [对于l1] 元音数量:6 [对于l2] 单词数量:3....不,错误。抱歉。这也可以工作。谢谢 - DragonClaw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接