C 行数神秘?

C 行数神秘?,c,lines,C,Lines,我的目标是实现一个计算文件中行数的函数。空文件被认为没有行。如果给定文件的最后一行不是空的,则应将其计为一行,尽管它没有以换行符结尾 我想出了以下代码: 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 = fg

我的目标是实现一个计算文件中行数的函数。空文件被认为没有行。如果给定文件的最后一行不是空的,则应将其计为一行,尽管它没有以换行符结尾

我想出了以下代码:

   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;
}

然而,即使在玩了一个多小时后,我也不明白为什么它的返回值线在某些情况下太大了…

你已经很接近了,这里是如何做到的:

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\u line
,并将其用作标志

如果我们刚开始读一行,我们将其设置为1(true);如果我们刚遇到一行新行(行尾),我们将其设置为0(false)

现在,如果我们有类似于:

1[newline]
2[newline]
3
我们会没事的,因为我们需要在读取文件后检查
read\u line
。因此,我们必须将行计数器增加1

这也可以:

1[newline]
2[newline]
3[newline]
因为我们看到了三个新行,并且在我们读取文件后,
read\u行
是0

这种情况也是如此:

1[newline]
2[newline]
3[newline]
[nothing here]
因为读取文件后,我们的标志将等于0,因为第三个换行符应该将其设置为0,并且我们实际上从未在循环中输入第四行,因为没有任何内容可读取

在您以前的实施中,如评论中所述,这一行:

if(c!='\n'&&&!isspace(c))

将在
c
等于
EOF
的情况下执行


或者你可以使用它,你就完成了。检查示例:

#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;
}
#包括
#包括
#定义bufsize1024
int main(int argc,char*argv[])
{
文件*fp;
字符buf[bufSize];
if((fp=fopen(“test.txt”、“rb”))==NULL)
{/*开源文件*/
perror(“fopen源文件”);
返回1;
}
int行=0;
while(fgets(buf,sizeof(buf),fp)!=NULL)
{/*而我们还没有到达源代码的末尾*/
/*从源文件读取字符以填充缓冲区*/
/*fgets将在找到换行符时停止*/
行++;
}
printf(“行=%d\n”,行);
fclose(fp);
返回0;
}
修改样本

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;
}

一个简单的解决方案可以是

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;
}

如果(c!='\n'&&&!isspace(c))
c
EOF
,当这一行出现时。告诉你的文本编辑器不要在文件末尾添加一行。
isspace
的CoolGuy参数是
int
。我同意@BLUEPIXY。它应该返回false。@BLUEPIXY,我支持更正。感谢您提供的信息,当一行大于缓冲区大小时,会导致计数错误。当然@BLUEPIXY,这就是可以对其进行微调的原因。:)