我正在学习文件流。我在使用ifstream在main之外的单独函数时遇到问题。在主内部它工作得很好。功能就是这样,
void counter(string str)
{
ifstream inpufile(str,ios::in);//the error is here, it says the function cannot be called!?!
if(!inpufile)
{
cout<<"\n The file does not exist, try again";
}
else
{
char c;
int counter=0;
while(inpufile.get(c))
{
if(c=='\n')
counter++;
}
cout<<"\n The number of lines in the file are "<<counter+1;
}
inpufile.close();
}
函数调用来自main(),就是这样的
counter(argv[1]);
我是否只能将ifstream作为对象传递。我可以不创建一个外部主体吗?
答案 0 :(得分:3)
你的问题与该函数没有任何关系,它与保存文件名的变量有关。考虑:
int main(int argc, const char** argv)
{
std::ifstream inpufile(argv[1], ios::in); // ok
std::string fname = argv[1]; // ok
std::ifstream fileb(str, ios::in); // fails pre-C++11
}
通过使用函数,您将导致从const char*
到std::string
的隐式转换,就像上面的示例一样。并且std::fstream
在C ++ 11之前没有使用std::string
作为文件名。两种解决方法:
void counter(const char* fname)
{
ifstream inpufile(fname, ios::in); // works now
和counter(argv[1]);
仍然有效,事实上它的效果更好一点,因为不需要转换。
或者
void counter(std::string fname)
{
ifstream inpufile(str.c_str(), ios::in); // ok too
获得const char*
期望的fstream
。
C ++ 11最终解决了这个问题,让你直接使用std::string
。
答案 1 :(得分:1)
是的,您可以在函数内创建它。功能正确。
如果(在C ++ 11之前)您需要将std::string
转为char*
,您可以使用c_str()
。
所以改变这个:
ifstream inpufile(str,ios::in);
到此:
ifstream inpufile(str.c_str(),ios::in);
你可以这样做:
void counter(string str, ifstream& inpufile) {
if (!inpufile) {
cout << "\n The file does not exist, try again";
} else {
char c;
int counter = 0;
while (inpufile.get(c)) {
if (c == '\n')
counter++;
}
cout << "\n The number of lines in the file are " << counter + 1;
}
inpufile.close();
}
int main() {
string str = "Team.txt";
ifstream inpufile(str.c_str(), ios::in);
counter(str, inpufile);
return 0;
}
你也可以在main中创建文件对象,然后在函数内打开它:
void counter(string str, ifstream& inpufile) {
inpufile.open(str.c_str(), ios::in);
if (!inpufile) {
cout << "\n The file does not exist, try again";
} else {
char c;
int counter = 0;
while (inpufile.get(c)) {
if (c == '\n')
counter++;
}
cout << "\n The number of lines in the file are " << counter + 1;
}
inpufile.close();
}
int main() {
string str = "Team.txt";
ifstream inpufile;
counter(str, inpufile);
return 0;
}
您的代码使用文件名提供函数,然后在函数内创建文件对象。
答案 2 :(得分:1)
ifstream inpufile(str.c_str());
ios::in
并非必要,因为它是隐式设置的。