我有一个功能,该功能应该计算用户输入的文件中的行数。但是,无论何时输入文件,我的函数都会返回0行。
int findnum_lines(FILE* fp){
int num_lines = 0;
char line;
int size;
size = ftell(fp);
line = getc(fp);
if(size != 0){
while(line != EOF){
if(line == '\n'){
num_lines = num_lines + 1;
}
line = getc(fp);
}
} else {
num_lines = 0;
}
printf("%d", num_lines);
return num_lines;
}
int main(int argc, char* argv[]){
char** lines = NULL;
int num_lines = 0;
FILE* fp = validate_input(argc, argv);
num_lines = findnum_lines(fp);
read_lines(fp, &lines, &num_lines);
print_lines(lines, num_lines);
free_lines(lines, num_lines);
fclose(fp);
return 0;
}
我的示例文件是:
Hello Class
This is what I would call a normal file
It isn't very special
But it still is important
所以我的函数应该返回4行,而不是0。
已更新:
int findnum_lines(FILE* fp){
int num_lines = 0;
int line;
line = getc(fp);
while(line != EOF){
if(line == '\n'){
num_lines = num_lines + 1;
}
line = getc(fp);
}
printf("%d", num_lines);
return num_lines;
}
int main(int argc, char* argv[]){
char** lines = NULL;
int num_lines = 0;
FILE* fp = validate_input(argc, argv);
num_lines = findnum_lines(fp);
read_lines(fp, &lines, &num_lines);
print_lines(lines, num_lines);
free_lines(lines, num_lines);
fclose(fp);
return 0;
}
使用此更新的代码,不会打印num_lines。
答案 0 :(得分:4)
ftell
报告文件中的当前位置。对于刚刚打开的文件,位置是开始,ftell
返回零。然后,由于size
为零,因此findnum_lines
中的循环处理零个字符,并报告未找到任何行。
通常,您不想获取文件大小然后循环播放。原因之一是文件在读取时可能会更改-其他进程可能会向其中写入更多数据或截断它。另一个原因是不必要的。只需使用EOF
循环(或while
循环)读取字符,直到获得do … while
。
另外,char line;
应该是int line;
,因为它用于保存getc
的结果(可以是字符或EOF
)和{{1 }}不足以容纳char
。 (此外,EOF
将字符的值作为getc
转换为unsigned char
的返回值,因此,在对int
进行签名的实现中,char
甚至不能正确地代表所有字符。)
答案 1 :(得分:2)
一个问题是对at main.Game.playSound(Game.java:102)
at main.Game.playTreasureSound(Game.java:115)
at main.Game.collisionCheck(Game.java:218)
at main.Game.access$1(Game.java:200)
at main.Game$1.handle(Game.java:240)
at javafx.animation.AnimationTimer$AnimationTimerReceiver.lambda$handle$484(AnimationTimer.java:57)
at java.security.AccessController.doPrivileged(Native Method)
at javafx.animation.AnimationTimer$AnimationTimerReceiver.handle(AnimationTimer.java:56)
at com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(AbstractMasterTimer.java:357)
at com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(AbstractMasterTimer.java:267)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:506)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:490)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$404(QuantumToolkit.java:319)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
的调用是在文件偏移仍为零的情况下完成的:
ftell()
如果在打开文件后立即调用int findnum_lines(FILE* fp){
int num_lines = 0;
int line; // changed char to int
int size;
size = ftell(fp);
line = getc(fp);
if(size != 0){
while(line != EOF){
if(line == '\n'){
num_lines = num_lines + 1;
}
line = getc(fp);
}
} else {
num_lines = 0;
}
printf("%d", num_lines);
return num_lines;
}
,则findnum_lines()
返回的文件当前偏移量将位于文件的开头-或为零。
因此ftell()
设置为零,并返回零。
请注意,由于要计算换行符-num_lines
,因此不需要检查文件大小-长度为零的文件将包含零个换行符。