如果我在我的代码中包含if测试,则返回错误消息,我不知道为什么。 当它没有被使用时,我的程序被卡在一个永远不会到达文件末尾的循环中。我不明白出了什么问题。
int countlines()
{
fstream myfile;
myfile.open("questions.txt", ios::in);
string contents;
int linenumber = 0;
//if (myfile.is_open())
// {
while (!myfile.eof())
{
getline( myfile, contents );
if (contents != "")
{
linenumber++;
}
}
cout << "there are " << linenumber << " lines.\n";
//}else {cout<<"Unable to get file.\n";}
myfile.close();
return(linenumber);
}
答案 0 :(得分:3)
发生的事情是您的文件未被打开。这就是is_open
失败的原因。
然后,当你注释掉支票时,你正在打破你的循环,因为你的迭代不正确(参见我的评论)而没有检测到流失败(.eof()
永远不会该流上的true
。
确保文件位于正确的位置,并且可以访问。
答案 1 :(得分:2)
使用std::istream
和std::ostream
(其std::fstream
实现)时,建议的用法是直接在bool上下文中使用流而不是调用eof()
函数,因为它只有在您设法读取文件的最后一个字节时才返回true
。如果之前有任何错误,该函数仍将返回true
。
所以,您应该将代码编写为:
int countlines() {
ifstream myfile;
int linenumber = 0;
string linecontent;
myfile.open("question.txt", ios::in);
while (getline(myfile, linecontent)) {
if (!linecontent.empty()) {
++linenumber;
}
}
return linenumber;
}
答案 2 :(得分:2)
在C ++中逐行读取文件的正确习惯是使用这样的循环:
for (std::string line; std::getline(file,line);)
{
// process line.
}
在您的示例中插入此内容(+修复缩进和变量名称),如下所示:
int countlines(const std::string& path)
{
// Open the file.
std::ifstream file(path.c_str());
if (!file.is_open()) {
return -1; // or better, throw exception.
}
// Count the lines.
int count = 0;
for (std::string line; std::getline(file,line);)
{
if (!line.empty()) {
++count;
}
}
return count;
}
请注意,如果您不打算处理行内容,实际上可以使用std::streambuf_iterator
跳过处理它们,这可以使您的代码看起来像:
int countlines(const std::string& path)
{
// Open the file.
std::ifstream file(path.c_str());
if (!file.is_open()) {
return -1; // or better, throw exception.
}
// Refer to the beginning and end of the file with
// iterators that process the file character by character.
std::istreambuf_iterator<char> current(file);
const std::istreambuf_iterator<char> end;
// Count the number of newline characters.
return std::count(current, end, '\n');
}
第二个版本将完全绕过复制文件内容,避免为长行分配大块内存。
答案 3 :(得分:0)
尝试以下代码。它(希望)也会让你知道为什么文件打开失败......
int countlines()
{
ifstream myfile;
myfile.open("questions.txt");
string contents;
int linenumber = 0;
if (myfile.is_open())
{
while (getline(myfile, contents))
{
if (contents != "")
linenumber++;
}
cout << "there are " << linenumber << " lines." << endl;
myfile.close();
}
else
cout << "Unable to get file (reason: " << strerror(errno) << ")." << endl;
return linenumber;
}