计算文件行数的C函数

vvppvyoh  于 2022-12-17  发布在  其他
关注(0)|答案(9)|浏览(209)

当我试图运行我的程序时,我得到了错误的打印行数。

LINES: 0

虽然.txt文件中有五行,但这是输出
下面是我的程序:

#include<stdio.h>
#include<stdlib.h>

int countlines(char *filename);

void main(int argc, char *argv[])
{
  printf("LINES: %d\n",countlines(argv[1]));         
}

int countlines(char *filename)
{
  // count the number of lines in the file called filename                                    
  FILE *fp = fopen(filename,"r");
  int ch=0;
  int lines=0;

  if (fp == NULL);
  return 0;

  lines++;
  while ((ch = fgetc(fp)) != EOF)
    {
      if (ch == '\n')
    lines++;
    }
  fclose(fp);
  return lines;
}

我相信这是一个简单的错误,但我是新的编程。任何帮助将不胜感激。

esbemjvw

esbemjvw1#

while(!feof(fp))
{
  ch = fgetc(fp);
  if(ch == '\n')
  {
    lines++;
  }
}

但请注意:Why is “while ( !feof (file) )” always wrong? .

6psbrbz9

6psbrbz92#

你宣布

int countlines(char *filename)

以接受char *参数。
你这样叫它

countlines(fp)

传入FILE *。
这就是为什么会出现编译错误。
你也许应该把第二行改成

countlines("Test.txt")

因为您在 * 计数行 * 中打开文件
当前代码试图在两个不同的位置打开该文件。

jmo0nnb3

jmo0nnb33#

你有;在if的末尾。更改:

if (fp == NULL);
  return 0;

if (fp == NULL) 
    return 0;
sd2nnvve

sd2nnvve4#

你正在打开一个文件,然后把文件指针传递给一个只需要文件名的函数来打开文件本身。

void main(void)
{
  printf("LINES: %d\n",countlines("Test.txt"));
}

编辑:你改变了问题,所以很难回答;一开始你对main()的修改是错误的,你忘记了第一个参数是argc,所以它崩溃了。

if (fp == NULL);   // <-- note the extra semicolon that is the only thing 
                   //     that runs conditionally on the if 
  return 0;        // Always runs and returns 0

它将始终返回0。删除多余的分号,您应该会得到一个合理的计数。

gk7wooem

gk7wooem5#

下面是我的函数

char *fileName = "input-1.txt";
countOfLinesFromFile(fileName);

void countOfLinesFromFile(char *filename){
FILE* myfile = fopen(filename, "r");
int ch, number_of_lines = 0;
do
{
    ch = fgetc(myfile);
    if(ch == '\n')
        number_of_lines++;
}
while (ch != EOF);
if(ch != '\n' && number_of_lines != 0)
    number_of_lines++;
fclose(myfile);
printf("number of lines in  %s   = %d",filename, number_of_lines);

}

hk8txs48

hk8txs486#

接受的答案需要34(!)秒来计算我的酷睿i9 CPU和SSD驱动器上的1.3 Gb CSV文件的行数。请不要使用fgetc来读取大文件。这是非常慢的。以下代码段在300毫秒内完成这项工作:

#include <stdio.h>

#define BUF_SIZE 65536

int count_lines(FILE* file)
{
    char buf[BUF_SIZE];
    int counter = 0;
    for(;;)
    {
        size_t res = fread(buf, 1, BUF_SIZE, file);
        if (ferror(file))
            return -1;

        int i;
        for(i = 0; i < res; i++)
            if (buf[i] == '\n')
                counter++;

        if (feof(file))
            break;
    }

    return counter;
}
uubf1zoe

uubf1zoe7#

我看不出有什么明显的东西会导致分段错误,我唯一的怀疑是,当你运行代码时,它期望得到一个文件名作为参数,但是如果你不传递它,它还是会试图引用一个文件名。
argv[1]不存在时访问它 * 将 * 导致分段错误。**通常在尝试引用参数之前检查参数的数量是一个好的实践。**您可以通过使用main()的以下函数原型并检查argc是否大于1(简单地说,它将指示argv中的条目数)来完成此操作。

int main(int argc, char** argv)

找出导致segfault的原因的最好方法是使用调试器。如果你在Visual Studio中,在主函数的顶部放置一个断点,然后在启动程序时选择“带调试运行”而不是“不带调试运行”。它将在顶部停止执行,并允许你逐行执行,直到你发现问题。
如果你使用Linux,你可以直接获取core文件(文件名中有“core”),然后用gdb(GNU Debugger)加载它,它会给予你一个堆栈转储,直接指向导致分段错误的行。
编辑:我看到你修改了你的问题和代码。所以这个答案可能不再有用了,但我还是把它当作一个好建议,看看我是否能很快解决修改后的问题)。

1hdlvixo

1hdlvixo8#

我觉得@Lundin的答案几乎是正确的,但是你需要在循环外添加一个(lines++)命令,因为最后一行不包含\n,所以不计算在内。

b1zrtrql

b1zrtrql9#

下面是C/C++中的完整实现

#include <stdio.h>

void lineCount(int argc,char **argv){

        if(argc < 2){
             fprintf(stderr,"File required");
             return;
        }
        FILE *fp = fopen(argv[1],"r");


        if(!fp){
            fprintf(stderr,"Error in opening file");
            return ;      
        }

        int count = 1; //if a file open ,be it empty, it has atleast a newline char
        char temp;

        while(fscanf(fp,"%c",&temp) != -1){
                if(temp == 10) count++;
        }

        fprintf(stdout,"File has %d lines\n",count);
   }

int main(int argc,char **argv){

        lineCount(argc,argv);
        return 0;
}
https://github.com/KotoJallow/Line-Count/blob/master/lineCount.c

相关问题