Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.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
在ANSI C中,计算文本文件中的行和字的最快方法是什么?_C_Text Files - Fatal编程技术网

在ANSI C中,计算文本文件中的行和字的最快方法是什么?

在ANSI C中,计算文本文件中的行和字的最快方法是什么?,c,text-files,C,Text Files,用纯ANSI C计算文本文件中的行和字的最快方法是什么 字以空格或句点结尾。行由'\n'终止 在中读取文件 迭代字符递增字符计数器 检查空格/行尾是否递增字计数器 重复第二步和第三步,直到EOF 这里是一个明确的答案,它计算行数(扩展到单词的数目是微不足道的),链接到在OP中的C++版本。此版本已缓冲。另一个答案是,首先读取整个文件,这是简单的,但是下面的内容更符合C++实例的工作。 #include <stdio.h> #include <string.h> #d

用纯ANSI C计算文本文件中的行和字的最快方法是什么

字以空格或句点结尾。行由
'\n'
终止

  • 在中读取文件
  • 迭代字符递增字符计数器
  • 检查空格/行尾是否递增字计数器
  • 重复第二步和第三步,直到
    EOF

这里是一个明确的答案,它计算行数(扩展到单词的数目是微不足道的),链接到在OP中的C++版本。此版本已缓冲。另一个答案是,首先读取整个文件,这是简单的,但是下面的内容更符合C++实例的工作。

#include <stdio.h>
#include <string.h>

#define BUFSIZE 1024

int main(int argc, char** argv)
{
  int newlines = 0;
  char buf[BUFSIZE];
  FILE* file;

  if (argc != 2)
    return 1;

  file = fopen(argv[1], "r");
  while (fgets(buf, BUFSIZE, file))
  {
    if (!(strlen(buf) == BUFSIZE-1 && buf[BUFSIZE-2] != '\n'))
      newlines++;
  }

  printf("Number of lines in %s: %d\n", argv[1], newlines);

  return 0;
}
#包括
#包括
#定义bufsize1024
int main(int argc,字符**argv)
{
int换行符=0;
字符buf[BUFSIZE];
文件*文件;
如果(argc!=2)
返回1;
file=fopen(argv[1],“r”);
while(fgets(buf、BUFSIZE、file))
{
如果(!(strlen(buf)==BUFSIZE-1和&buf[BUFSIZE-2]!='\n'))
换行符++;
}
printf(“在%s中的行数:%d\n”,argv[1],换行符);
返回0;
}

BUFSIZE宏可以调整以最大限度地提高性能(因为您说您想要最快的方式)。1024只是一个猜测。另一种可能是读取文件内存映射,但我没有尝试,因为mmap不是ANSI C。

也许可以看看GNUwc实用程序的源代码,因为该实用程序正是您想要的

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

typedef unsigned long count_t;  /* Counter type */

/* Current file counters: chars, words, lines */
count_t ccount;
count_t wcount;
count_t lcount;

/* Totals counters: chars, words, lines */
count_t total_ccount = 0;
count_t total_wcount = 0;
count_t total_lcount = 0;

/* Print error message and exit with error status. If PERR is not 0,
   display current errno status. */
static void
error_print (int perr, char *fmt, va_list ap)
{
  vfprintf (stderr, fmt, ap);
  if (perr)
    perror (" ");
  else
    fprintf (stderr, "\n");
  exit (1);  
}

/* Print error message and exit with error status. */
static void
errf (char *fmt, ...)
{
  va_list ap;

  va_start (ap, fmt);
  error_print (0, fmt, ap);
  va_end (ap);
}

/* Print error message followed by errno status and exit
   with error code. */
static void
perrf (char *fmt, ...)
{
  va_list ap;

  va_start (ap, fmt);
  error_print (1, fmt, ap);
  va_end (ap);
}

/* Output counters for given file */
void
report (char *file, count_t ccount, count_t wcount, count_t lcount)
{
  printf ("%6lu %6lu %6lu %s\n", lcount, wcount, ccount, file);
}

/* Return true if C is a valid word constituent */
static int
isword (unsigned char c)
{
  return isalpha (c);
}

/* Increase character and, if necessary, line counters */
#define COUNT(c)       \
      ccount++;        \
      if ((c) == '\n') \
        lcount++;

/* Get next word from the input stream. Return 0 on end
   of file or error condition. Return 1 otherwise. */
int
getword (FILE *fp)
{
  int c;
  int word = 0;

  if (feof (fp))
    return 0;

  while ((c = getc (fp)) != EOF)
    {
      if (isword (c))
        {
          wcount++;
          break;
        }
      COUNT (c);
    }

  for (; c != EOF; c = getc (fp))
    {
      COUNT (c);
      if (!isword (c))
        break;
    }

  return c != EOF;
}

/* Process file FILE. */
void
counter (char *file)
{
  FILE *fp = fopen (file, "r");

  if (!fp)
    perrf ("cannot open file `%s'", file);

  ccount = wcount = lcount = 0;
  while (getword (fp))
    ;
  fclose (fp);

  report (file, ccount, wcount, lcount);
  total_ccount += ccount;
  total_wcount += wcount;
  total_lcount += lcount;
}

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

  if (argc < 2)
    errf ("usage: wc FILE [FILE...]");

  for (i = 1; i < argc; i++)
    counter (argv[i]);

  if (argc > 2)
    report ("total", total_ccount, total_wcount, total_lcount);
  return 0;
}
#包括
#包括
#包括
typedef无符号长计数\u t;/*计数器类型*/
/*当前文件计数器:字符、字、行*/
计数帐户;
计数;
计数;
/*总计计数器:字符、字、行*/
总计数=0;
总计数=0;
总计数=0;
/*打印错误消息并以错误状态退出。如果PERR不是0,
显示当前errno状态*/
静态空隙
打印错误(int perr、char*fmt、VAU list ap)
{
vfprintf(标准、fmt、ap);
如果(perr)
佩罗尔(“”);
其他的
fprintf(标准格式,“\n”);
出口(1);
}
/*打印错误消息并以错误状态退出*/
静态空隙
errf(字符*fmt,…)
{
va_列表ap;
va_启动(ap、fmt);
打印错误(0,fmt,ap);
va_端(ap);
}
/*打印错误消息,后跟errno状态并退出
带有错误代码*/
静态空隙
perrf(字符*fmt,…)
{
va_列表ap;
va_启动(ap、fmt);
打印错误(1,fmt,ap);
va_端(ap);
}
/*给定文件的输出计数器*/
无效的
报告(字符*文件、计数、计数、计数)
{
printf(“%6lu%6lu%6lu%s\n”,lcount,wcount,ccount,file);
}
/*如果C是有效的单词成分,则返回true*/
静态整数
isword(无符号字符c)
{
返回isalpha(c);
}
/*增加字符计数器,必要时增加行计数器*/
#定义计数(c)\
ccount++\
如果((c)='\n')\
lcount++;
/*从输入流中获取下一个单词。结束时返回0
指文件或错误状态。否则返回1*/
int
getword(文件*fp)
{
INTC;
int字=0;
if(feof(fp))
返回0;
而((c=getc(fp))!=EOF)
{
if(isword(c))
{
wcount++;
打破
}
计数(c);
}
对于(;c!=EOF;c=getc(fp))
{
计数(c);
如果(!isword(c))
打破
}
返回c!=EOF;
}
/*处理文件*/
无效的
计数器(字符*文件)
{
文件*fp=fopen(文件“r”);
如果(!fp)
perrf(“无法打开文件“%s”,文件);
ccount=wcount=lcount=0;
while(getword(fp))
;
fclose(fp);
报告(文件、帐户、wcount、lcount);
合计_账户+=账户;
总计数+=总计数;
总数_lcount+=lcount;
}
int
主(内部argc,字符**argv)
{
int i;
如果(argc<2)
errf(“用法:wc文件[文件…]”);
对于(i=1;i2)
报告(“总计”,合计,合计,合计);
返回0;
}
网址:
如果你只需要从文件中读取ANSI C方式,那么C++链接的解决方案应该直接转换成C,不是吗?因此,据我所见,这使得问题本质上“如何读取ANSI C中的文件?”定义“单词”和“行”非常好。
“Mc'Donalds”是一个词吗?那么
“RS232C”
“transli-\n指定的”
呢?在前面的例子中,Word?它大约有800行代码,但效率很高,而且经过了很好的测试。根据您对“单词”和“行”的定义,在一个包含3个空格、一个换行符、3个句点(总共7个字符)的文件中,有多少个单词和行?这种方法在网络上广泛使用。JMSA:是的,但它也是(几乎,除了缓冲外)在C++实例中使用的链接方法,所以它听起来像你想要的。这是一个相当过时的版本,运行速度非常慢,与WC的二进制传输相比;请参阅此版本,一个只有一个字且没有行分隔符的文件将注册0行而不是1行。请参阅:这不处理最后一行未使用行分隔符终止的情况。为此,您需要一个状态机。它也不容易扩展到计算单词,因为这也需要一个状态机。