sil*_*ent 24 c++ text gcc file
我正在阅读文本文件中的行,我想知道这是否是一个好方法?我必须编写函数numberoflines来减少number_of_lines variable一个,因为在while循环中,对于它读取的每一行,它都会向number_of_lines变量添加2.
#include <iostream>
#include <fstream>
using namespace std;
int number_of_lines = 0;
void numberoflines();
int main(){
string line;
ifstream myfile("textexample.txt");
if(myfile.is_open()){
while(!myfile.eof()){
getline(myfile,line);
cout<< line << endl;
number_of_lines++;
}
myfile.close();
}
numberoflines();
}
void numberoflines(){
number_of_lines--;
cout<<"number of lines in text file: " << number_of_lines << endl;
}
Run Code Online (Sandbox Code Playgroud)
还有其他更容易更好的方法吗?
Jer*_*fin 55
你在最后减少计数的黑客就是那个 - 一个黑客.
首先正确编写循环要好得多,所以它不会计算最后一行两次.
int main() {
int number_of_lines = 0;
std::string line;
std::ifstream myfile("textexample.txt");
while (std::getline(myfile, line))
++number_of_lines;
std::cout << "Number of lines in text file: " << number_of_lines;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我个人认为,在这种情况下,C风格的代码是完全可以接受的:
int main() {
unsigned int number_of_lines = 0;
FILE *infile = fopen("textexample.txt", "r");
int ch;
while (EOF != (ch=getc(infile)))
if ('\n' == ch)
++number_of_lines;
printf("%u\n", number_of_lines);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑:当然,C++也会让你做一些类似的事情:
int main() {
std::ifstream myfile("textexample.txt");
// new lines will be skipped unless we stop it from happening:
myfile.unsetf(std::ios_base::skipws);
// count the newlines with an algorithm specialized for counting:
unsigned line_count = std::count(
std::istream_iterator<char>(myfile),
std::istream_iterator<char>(),
'\n');
std::cout << "Lines: " << line_count << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我认为你的问题是,"我为什么要获得比文件中更多的一行?"
想象一个文件:
line 1
line 2
line 3
Run Code Online (Sandbox Code Playgroud)
该文件可以用ASCII表示,如下所示:
line 1\nline 2\nline 3\n
Run Code Online (Sandbox Code Playgroud)
(\n字节在哪里0x10.)
现在让我们看看每次getline通话之前和之后会发生什么:
Before 1: line 1\nline 2\nline 3\n
Stream: ^
After 1: line 1\nline 2\nline 3\n
Stream: ^
Before 2: line 1\nline 2\nline 3\n
Stream: ^
After 2: line 1\nline 2\nline 3\n
Stream: ^
Before 2: line 1\nline 2\nline 3\n
Stream: ^
After 2: line 1\nline 2\nline 3\n
Stream: ^
Run Code Online (Sandbox Code Playgroud)
现在,您认为流将标记eof为表示文件的结尾,对吧?不!这是因为getline套eof如果达到最终的文件标记"期间,它的操作".因为getline在到达时终止,所以\n不读取文件结束标记,并且eof不标记该标记.因此,myfile.eof()返回false,循环经历另一次迭代:
Before 3: line 1\nline 2\nline 3\n
Stream: ^
After 3: line 1\nline 2\nline 3\n
Stream: ^ EOF
Run Code Online (Sandbox Code Playgroud)
你是如何解决这个问题的?而不是检查eof(),看看是否.peek()返回EOF:
while(myfile.peek() != EOF){
getline ...
Run Code Online (Sandbox Code Playgroud)
您还可以检查getline(隐式转换为bool)的返回值:
while(getline(myfile,line)){
cout<< ...
Run Code Online (Sandbox Code Playgroud)