不使用fgets打印文件中的行数 [英] Printing number of lines in a file without using fgets

查看:80
本文介绍了不使用fgets打印文件中的行数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在尝试打印文件中的行数.问题是我不能使用fgets.还有其他替代方法,仅涉及fscanf吗? 我尝试运行以下命令:

So I am trying to print the number of lines in a file. The catch is that I cannot use fgets. Is there any other alternative to this which involves only fscanf? I tried running the following:

while (1) {
  ret = fscanf(fin, "%[^\n]", string);
  if (ret == EOF) break;
  line_count++;
}

但是它不起作用.它给了我一个无限循环.谁能告诉我问题是什么?

But it does not work. It is giving me an infinite loop. Can anyone please tell me what the issue is ?

推荐答案

您还必须注意其他答案未涵盖的 corner-case .为了使文件符合POSIX,最后一个字符必须为'\n'字符,否则文件开头可能为空.例如,包含POSIX文件结尾的两行文件可能是:

You must also be aware of a corner-case not covered by the other answers. For a file to be POSIX compliant, the final character must be a '\n' character, or the file may be empty to begin with. For example, a two line file that contains a POSIX end-of-file could be:

my dog has fleas\n
my cat has none\n

如果您通过计算'\n'字符的数量来计算上面文件中的行数,则文件的行数将与预期的一样-2.但是,当今有许多编辑器无法创建POSIX兼容文件,因为它们无法在文本的最后一行之后写入最终的'\n'.如此多的编辑器会将文件保留为:

If you were counting lines in the file above by counting the number of '\n' characters, your number of lines for the file would be as expected -- 2. However, there are many editors today, that do no create POSIX compliant files because they fail to write the final '\n' after the last line of text. So many editors would leave the file as:

my dog has fleas\n
my cat has none

这是保存文件的一种完全合法的方法,但这只是一种非POSIX的方法.现在,如果仅计算'\n'字符来确定文件中的行,程序将输出什么? (1-您会数到几行)

It is a perfectly legal way to save the file, it is just a non-POSIX way of doing so. Now, what would your program output if you were simply counting the '\n' characters to determine the lines in the file? (1 -- you would count one-too-few lines)

要解决非POSIX eof的问题以确保行数正确,您需要检查EOF之前的最后一个字符,看看它是否是'\n',是否不是.您需要在行数中添加+1.

To address the issue of a non-POSIX eof to ensure your line count is correct either way, you need to check the last character before EOF and see if it was a '\n', and if it wasn't you need to add +1 to your line count.

您可以相当简单地做到这一点,只需在循环结束时保存当前字符即可,以便在遇到EOF后保留当前字符以进行比较.您可以执行以下操作:

You can do that fairly simply just by saving the current character at the end of you loop so that it is preserved for comparison after EOF is encountered. You can do something like the following:

/* count lines in file from open file-stream.
 * returns number of lines in file, including files
 * with non-POSIX end-of-file.
 */
size_t linecount (FILE *fp)
{
    int c, last = 0;                    /* current and last char read */
    size_t nlines = 0;                  /* line counter */
    
    rewind(fp);                         /* prevent UB if EOF already set on fp */
    
    while ((c = fgetc(fp)) != EOF) {    /* loop reading each char */
        if (c == '\n')                  /* if '\n' increment line counter */
            nlines++;
        last = c;                       /* save current as last */
    }
    /* if not empty-file and not POSIX eof, add 1 to nlines */
    return last && last != '\n' ? nlines + 1 : nlines;
}

循环也可以写成:

    do {
        last = c;
        if ((c = fgetc(fp)) == '\n')
            nlines++;
    } while (c != EOF);

仔细检查一下,如果还有其他问题,请告诉我.

Look things over and let me know if you have further questions.

这篇关于不使用fgets打印文件中的行数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆