读取目录中具有相同扩展名的文件并计算它们的行数
Reading files with the same extension in a directory and count their lines
我的代码有这个问题。我一直在尝试打开具有相同扩展名的文件并读取目录中文件的行数。
所以,这就是我所做的:
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
int countLines(char name[]);
int main()
{
struct dirent *de;
DIR *dr=opendir(".");
char check[16]=".nkt";
int i;
char name[64];
int count=0;
if(dr==NULL)
{
printf("Didn't open!");
return 0;
}
while((de=readdir(dr))!=NULL)
{
if((strstr(de->d_name, check))!=NULL)
{
strcpy(name, de->d_name);
countLines(name);
}
}
closedir(dr);
return 0;
}
int countLines(char name[])
{
FILE *fp;
fp=fopen(name,"r");
char ch;
int lines=0;
while(!feof(fp))
{
ch=fgetc(fp);
if(ch=='\n')
{
lines++;
}
}
fclose(fp);
printf("%d\n", lines);
}
我得到的结果总是这样的:
2
2
2
即使每个文件有 54 行。
很乐意提供一些帮助。
PS。扩展名为 .nkt
您显示的 countLines()
函数正步入多个陷阱。
fgetc()
returns int
不是 char
故意的。它这样做是为了能够 return 文件结束状态,除了所有其他可能的字符值。一个简单的 char
无法做到这一点。
使用 feof()
识别文件结尾失败,因为 EOF 指示符仅在最后一次读取文件末尾完成后设置。因此,使用 feof()
引导的循环通常迭代一次到经常。
对此的详细讨论是here。
文本文件的最后一行不一定带有文件结束指示符,但您很可能仍想计算该行。需要应用特殊逻辑来涵盖这种情况。
解决上述所有问题的函数的可能实现可能如下所示:
#include <stdio.h>
/* Returns the number of lines inside the file named file_name
or -1 on error. */
long count_lines(const char * file_name)
{
long lines = 0;
FILE * fp = fopen(file_name, "r"); /* Open file to read in text mode. */
if (NULL == fp)
{
lines = -1;
}
else
{
int previous = EOF;
for (int current; (EOF != (current = fgetc(fp)));)
{
if ('\n' == current)
{
++lines;
}
previous = current;
}
if (ferror(fp)) /* fgetc() returns EOF as well if an error occurred.
This call identifies that case. */
{
lines = -1;
}
else if (EOF != previous && '\n' != previous)
{
++lines; /* Last line missed trailing new-line! */
}
fclose(fp);
}
return lines;
}
关于问题评论部分中关于不同行尾指示符的讨论:
文本文件的行尾指示器在不同平台上的实现方式不同(UNIX:'\n'
与 Windows:\r\n
与 ...(https://en.wikipedia.org/wiki/Newline)).
为了解决这个问题,C 库函数 fopen()
默认情况下以所谓的“文本模式”打开文件。如果以这种方式打开,C 实现会注意将每一行的结尾 return 编辑为单个 '\n'
字符,即所谓的“换行”字符。请注意(如上文 3. 所述)最后一行可能根本没有行尾指示符。
我的代码有这个问题。我一直在尝试打开具有相同扩展名的文件并读取目录中文件的行数。 所以,这就是我所做的:
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
int countLines(char name[]);
int main()
{
struct dirent *de;
DIR *dr=opendir(".");
char check[16]=".nkt";
int i;
char name[64];
int count=0;
if(dr==NULL)
{
printf("Didn't open!");
return 0;
}
while((de=readdir(dr))!=NULL)
{
if((strstr(de->d_name, check))!=NULL)
{
strcpy(name, de->d_name);
countLines(name);
}
}
closedir(dr);
return 0;
}
int countLines(char name[])
{
FILE *fp;
fp=fopen(name,"r");
char ch;
int lines=0;
while(!feof(fp))
{
ch=fgetc(fp);
if(ch=='\n')
{
lines++;
}
}
fclose(fp);
printf("%d\n", lines);
}
我得到的结果总是这样的:
2
2
2
即使每个文件有 54 行。 很乐意提供一些帮助。 PS。扩展名为 .nkt
您显示的 countLines()
函数正步入多个陷阱。
fgetc()
returnsint
不是char
故意的。它这样做是为了能够 return 文件结束状态,除了所有其他可能的字符值。一个简单的char
无法做到这一点。使用
feof()
识别文件结尾失败,因为 EOF 指示符仅在最后一次读取文件末尾完成后设置。因此,使用feof()
引导的循环通常迭代一次到经常。对此的详细讨论是here。
文本文件的最后一行不一定带有文件结束指示符,但您很可能仍想计算该行。需要应用特殊逻辑来涵盖这种情况。
解决上述所有问题的函数的可能实现可能如下所示:
#include <stdio.h>
/* Returns the number of lines inside the file named file_name
or -1 on error. */
long count_lines(const char * file_name)
{
long lines = 0;
FILE * fp = fopen(file_name, "r"); /* Open file to read in text mode. */
if (NULL == fp)
{
lines = -1;
}
else
{
int previous = EOF;
for (int current; (EOF != (current = fgetc(fp)));)
{
if ('\n' == current)
{
++lines;
}
previous = current;
}
if (ferror(fp)) /* fgetc() returns EOF as well if an error occurred.
This call identifies that case. */
{
lines = -1;
}
else if (EOF != previous && '\n' != previous)
{
++lines; /* Last line missed trailing new-line! */
}
fclose(fp);
}
return lines;
}
关于问题评论部分中关于不同行尾指示符的讨论:
文本文件的行尾指示器在不同平台上的实现方式不同(UNIX:'\n'
与 Windows:\r\n
与 ...(https://en.wikipedia.org/wiki/Newline)).
为了解决这个问题,C 库函数 fopen()
默认情况下以所谓的“文本模式”打开文件。如果以这种方式打开,C 实现会注意将每一行的结尾 return 编辑为单个 '\n'
字符,即所谓的“换行”字符。请注意(如上文 3. 所述)最后一行可能根本没有行尾指示符。