我的目标是实现一个计算文件中行数的函数。并且空文件被认为没有行。如果给定文件的最后一行不为空,则应将其计为一行,尽管不以换行符结尾。
我已经提出以下代码:
int linecount(const char *filename)
{
FILE *f = fopen(filename, "r");
if(!f)
return -1;
int lines = 0;
int c = 0;
int n = 0;
while((c = fgetc(f)) != EOF){
if(c == '\n')
lines++;
n++;
}
if(n==0)
return 0; //return 0 if the file is empty
if(c!='\n' && !isspace(c))
lines++; //count the last line if it's not empty
fclose(f);
return lines;
}
然而,即使在玩了一个多小时后,我也无法弄清楚为什么它的返回值线在某些情况下太大了......
答案 0 :(得分:3)
你很接近,在这里你可以做到这一点:
int linecount(const char *filename) {
FILE *f = fopen(filename, "r");
if (!f)
return -1;
int lines = 0;
int c = 0;
int n = 0;
int read_line = 0;
while ((c = fgetc(f)) != EOF) {
read_line = 1;
if (c == '\n') {
lines++;
read_line = 0;
}
n++;
}
if (n == 0)
return 0; //return 0 if the file is empty
if(read_line)
lines++;
fclose(f);
return lines;
}
我们想要知道我们是否开始阅读一行,如果我们在这行的末尾遇到换行符。那么,我们使用另一个变量,称为read_line
我们用它作为旗帜。
如果我们刚刚开始读取一行,我们将其设置为1(true),如果我们刚刚遇到一个换行符(行尾),我们将其设置为0(假)。
现在,如果我们有类似的东西:
1[newline]
2[newline]
3
我们会好的,因为我们需要在读取文件后检查read_line
是否正确。是这样,我们必须将我们的行计数器增加一个。
这也没关系:
1[newline]
2[newline]
3[newline]
因为我们看到了三个换行符,并且在我们读取文件后read_line
为0。
同样适用于这种情况:
1[newline]
2[newline]
3[newline]
[nothing here]
因为我们的标志在读取文件后将等于0,因为第3个换行符应该设置为0,我们实际上从未在循环中输入第4行,因为没有什么可读的。
根据您之前的实施,如评论中所述,此行:
if(c!='\n' && !isspace(c))
将在c
等于EOF
的情况下执行。
或者你可以使用fgets()而且你已经完成了。检查示例:
#include <stdio.h>
#include <string.h>
#define bufSize 1024
int main(int argc, char *argv[])
{
FILE *fp;
char buf[bufSize];
if ((fp = fopen("test.txt", "rb")) == NULL)
{ /* Open source file. */
perror("fopen source-file");
return 1;
}
int lines = 0;
while (fgets(buf, sizeof(buf), fp) != NULL)
{ /* While we don't reach the end of source. */
/* Read characters from source file to fill buffer. */
/* fgets will stop when it finds a newline. */
lines++;
}
printf("lines = %d\n", lines);
fclose(fp);
return 0;
}
答案 1 :(得分:2)
修改样本
int linecount(const char *filename)
{
FILE *f = fopen(filename, "r");
if(!f)
return -1;
int lines = 0;
int c = 0;
int flag = 1;
while((c = fgetc(f)) != EOF){
if(flag = (c == '\n'))
lines++;
}
if(!flag)
lines++; //count the last line if it's not empty
fclose(f);
return lines;
}
答案 2 :(得分:1)
一个简单的解决方案可以是
int linecount(const char *filename)
{
FILE *stream;
char *line = NULL;
size_t len = 0;
ssize_t read;
int numOfLines = 0;
stream = fopen(filename, "r");
if (stream == NULL)
exit(EXIT_FAILURE);
while ((read = getline(&line, &len, stream)) != -1) {
numOfLines++;
}
free(line);
fclose(stream);
return numOfLines;
}