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