Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何计算文件中的换行,但不计算仅为换行的行?_C_File_Newline_C99_Fgets - Fatal编程技术网

C 如何计算文件中的换行,但不计算仅为换行的行?

C 如何计算文件中的换行,但不计算仅为换行的行?,c,file,newline,c99,fgets,C,File,Newline,C99,Fgets,为了正确解析输入,我需要能够计算文件中的行数。但是,我不想计算只是换行的行数。为此,我创建了以下函数: int countLinesInFile(char *filename) { int newlines = 0; if (access(filename,F_OK) != -1) error("File not found",0); FILE *input = fopen(filename,"r"); int size = 256 * 4; char buff

为了正确解析输入,我需要能够计算文件中的行数。但是,我不想计算只是换行的行数。为此,我创建了以下函数:

int countLinesInFile(char *filename) {
  int newlines = 0;

  if (access(filename,F_OK) != -1)
    error("File not found",0);

  FILE *input = fopen(filename,"r");

  int size = 256 * 4;
  char buffer[size];
  while ((fgets(buffer,sizeof(buffer),input)) != EOF) {
    printf("Read a string");
    if (buffer == "\n")
      continue;
    newlines++;
  }

  fclose(input);
  return newlines;
}
在文件的顶部,我有以下内容:

#include <stdio.h>
#include <unistd.h>
==6632== Invalid read of size 4
==6632==    at 0x4EA8E6B: fgets (in /usr/lib64/libc-2.24.so)
==6632==    by 0x402219: countLinesInFile (in [executable])
[other information about program, does not seem relevant]
==6632==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==6632== 
==6632== 
==6632== Process terminating with default action of signal 11 (SIGSEGV)
==6632==  Access not within mapped region at address 0x0
==6632==    at 0x4EA8E6B: fgets (in /usr/lib64/libc-2.24.so)
==6632==    by 0x402219: countLinesInFile (in [executable])
[other information about program, does not seem relevant]
==6632==  If you believe this happened as a result of a stack
==6632==  overflow in your program's main thread (unlikely but
==6632==  possible), you can try to increase the size of the
==6632==  main thread stack using the --main-stacksize= flag.
==6632==  The main thread stack size used in this run was 8388608.
==6632== 
==6632== HEAP SUMMARY:
==6632==     in use at exit: 475 bytes in 16 blocks
==6632==   total heap usage: 19 allocs, 3 frees, 3,075 bytes allocated
==6632== 
==6632== LEAK SUMMARY:
==6632==    definitely lost: 0 bytes in 0 blocks
==6632==    indirectly lost: 0 bytes in 0 blocks
==6632==      possibly lost: 0 bytes in 0 blocks
==6632==    still reachable: 475 bytes in 16 blocks
==6632==         suppressed: 0 bytes in 0 blocks
==6632== Rerun with --leak-check=full to see details of leaked memory
==6632== 
==6632== For counts of detected and suppressed errors, rerun with: -v
==6632== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
  while (fgets(buffer,sizeof(buffer),input)) {
    if (buffer[0] != '\n') {
      newlines++;
    }
  }
我试图在while循环的开头放一行,上面写着“printf(“读取文件”)”。这段代码不会执行,我相信fgets就是问题所在。不幸的是,我不知道这个问题是什么

我已经验证了我试图读取的文件中是否有正确的文本,并且不是空的

我创建的函数是否是此任务的正确方法?如果是,我会有什么问题?我将来如何避免这个问题


更新:这对我来说真是一个愚蠢的错误。我用Valgrind运行程序,看起来它没有使用可执行文件的目录,这意味着它找不到文件。感谢您的帮助。

我认为您需要跟踪上一次
\n
的文件偏移量,如果此
\n
==last+1,则不递增。

函数
fgets
返回指针值,失败时返回NULL。EOF(通常,除非您更改它)定义为-1。它们永远不会比较相等,这意味着您将在停止后很长时间调用fgets。

两件事:首先,
fgets
在无法读取更多行时返回
NULL
,而不是
EOF
。因此,条件应该是
while(fgets(…)!=NULL)
或short
while(fgets(…)
。 其次,
buffer==“\n”
比较两个指向字符的指针,即比较两个内存地址。而且,任何东西都不太可能与string literal
“\n”
具有相同的内存地址。因此,比较字符,即
buffer[0]='\n'
buffer[0]!='\n'
。 我认为您可以很容易地去掉
continue
-语句,这样代码看起来如下所示:

#include <stdio.h>
#include <unistd.h>
==6632== Invalid read of size 4
==6632==    at 0x4EA8E6B: fgets (in /usr/lib64/libc-2.24.so)
==6632==    by 0x402219: countLinesInFile (in [executable])
[other information about program, does not seem relevant]
==6632==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==6632== 
==6632== 
==6632== Process terminating with default action of signal 11 (SIGSEGV)
==6632==  Access not within mapped region at address 0x0
==6632==    at 0x4EA8E6B: fgets (in /usr/lib64/libc-2.24.so)
==6632==    by 0x402219: countLinesInFile (in [executable])
[other information about program, does not seem relevant]
==6632==  If you believe this happened as a result of a stack
==6632==  overflow in your program's main thread (unlikely but
==6632==  possible), you can try to increase the size of the
==6632==  main thread stack using the --main-stacksize= flag.
==6632==  The main thread stack size used in this run was 8388608.
==6632== 
==6632== HEAP SUMMARY:
==6632==     in use at exit: 475 bytes in 16 blocks
==6632==   total heap usage: 19 allocs, 3 frees, 3,075 bytes allocated
==6632== 
==6632== LEAK SUMMARY:
==6632==    definitely lost: 0 bytes in 0 blocks
==6632==    indirectly lost: 0 bytes in 0 blocks
==6632==      possibly lost: 0 bytes in 0 blocks
==6632==    still reachable: 475 bytes in 16 blocks
==6632==         suppressed: 0 bytes in 0 blocks
==6632== Rerun with --leak-check=full to see details of leaked memory
==6632== 
==6632== For counts of detected and suppressed errors, rerun with: -v
==6632== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
  while (fgets(buffer,sizeof(buffer),input)) {
    if (buffer[0] != '\n') {
      newlines++;
    }
  }
应该是

FILE *input;
input = fopen(filename,"r");
我不相信
fgets()
会返回换行符或EOF。它在换行之前的字符处停止读取,下一次读取将是换行或后续换行之后的字符

您可能需要使用二进制文件读取函数,该函数将一次性读取整个文件,然后解析出行。这也将处理文本文件末尾没有EOF的情况。很多人不这么认为

  • 获取文件的大小
  • 分配一个缓冲区来保存整个文件
  • 将整个文件读入缓冲区
  • 解析缓冲区

fgets()
将您限制为预定义的行长度。为了避免这种情况,你可以使用

在计算行数时,要跳过空行,您只需对与
“\n”
匹配的任何内容进行折扣即可:

#包括
...
长计数行(常量字符*文件名)
{
FILE*fp=fopen(文件名,“r”);
如果(fp==NULL)
{
返回(-1L);
}
char*line=NULL;
大小\u t字节=0UL;
长线计数=0L;
对于(;;)
{
ssize_t result=getline(&line,&bytes,fp);
如果(-1==结果)
{
打破
}
if(strcmp(第“\n”行)
{
lineCount++;
}
}
自由线;
fclose(fp);
返回(行计数);
}

首先检查
fopen
buffer=“\n”
的返回值,这不是在C中比较字符串的方法。需要使用
strcmp
或字符比较
buffer[0]='\n'
fgets
不返回
EOF
@BLUEPIXY我检查了fopen的输出,它说“找不到文件”,尽管在同一个目录中有一个“stuff.br”(正在打开的文件的名称,我已选中)。该文件是否与可执行文件存在于同一个目录中?在IDE中运行时,它通常不是同一个目录。尝试指定文件名的完整路径。此外,如果您从用户输入文件名,是否删除换行符?
file*input=fopen(filename,“r”)?“使用二进制文件读取功能”为什么文本文件需要二进制文件读取器?两行代码没有任何优点。您对
fgets()
的看法是错误的——特别是,它在数据中包含换行符,除非没有空间容纳它。它通过返回空指针指示EOF。完全不需要将整个文件读入缓冲区。您可以使用三个整数(最后一个字符、这个字符、总计数)和
getc()
完成这项工作。不幸的是,如果我添加了一行,每当它运行循环时都会打印,这意味着它将输出,我确实尝试过。不幸的是,事实并非如此。我想这意味着第一个fgets失败了。我这样做了,但它仍然失败。我认为问题在于fgets的第一次呼叫。