为什么我的wc实现给出了错误的字数?
下面是一个小代码片段为什么我的wc实现给出了错误的字数?,c,linux,string,algorithm,wc,C,Linux,String,Algorithm,Wc,下面是一个小代码片段 while((c = fgetc(fp)) != -1) { cCount++; // character count if(c == '\n') lCount++; // line count else { if(c == ' ' && prevC != ' ') wCount++; // word count } prevC
while((c = fgetc(fp)) != -1)
{
cCount++; // character count
if(c == '\n') lCount++; // line count
else
{
if(c == ' ' && prevC != ' ') wCount++; // word count
}
prevC = c; // previous character equals current character. Think of it as memory.
}
现在,当我运行wc
时,文件包含上述代码片段(原样),我得到48个单词,但当我在相同的输入数据上使用我的程序时,我得到59个单词
如何像wc一样精确地计算字数?与其只检查空格,不如检查转义序列,如空格等 这将给出正确的结果。 您可以从
换线
if(c == ' ' && prevC != ' ') wCount++;
到
这将给出正确的结果。
不要忘记包括
而不是只检查空格。您应该检查转义序列,如空格等
这将给出正确的结果。
您可以从
换线
if(c == ' ' && prevC != ' ') wCount++;
到
这将给出正确的结果。
不要忘记包含
您正在将任何非空格的内容视为有效单词。这意味着一个新行后跟一个空格就是一个单词,由于您的输入(即您的代码段)是缩进的,所以您会得到一堆额外的单词
您应该使用来检查空格,而不是将字符与''
进行比较:
while((c = fgetc(fp)) != EOF)
{
cCount++;
if (c == '\n')
lCount++;
if (isspace(c) && !isspace(prevC))
wCount++;
prevC = c;
}
你把任何不是空格的词都当作有效词。这意味着一个新行后跟一个空格就是一个单词,由于您的输入(即您的代码段)是缩进的,所以您会得到一堆额外的单词 您应该使用来检查空格,而不是将字符与
''
进行比较:
while((c = fgetc(fp)) != EOF)
{
cCount++;
if (c == '\n')
lCount++;
if (isspace(c) && !isspace(prevC))
wCount++;
prevC = c;
}
书中有一个函数示例:“Brian W Kernighan和Dennis M Ritchie:Ansi C编程语言”。正如作者所说:这是UNIX程序wc的基本版本。更改为仅计算单词如下:
#include <stdio.h>
#define IN 1 /* inside a word */
#define OUT 0 /* outside a word */
/* nw counts words in input */
main()
{
int c, nw, state;
state = OUT;
nw = 0;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}
printf("%d\n", nw);
}
#包括
#在1/*中定义一个单词*/
#在单词外定义0/**/
/*nw统计输入中的单词数*/
main()
{
州西北部国际中心;
状态=输出;
nw=0;
而((c=getchar())!=EOF){
如果(c=''| | c='\n'| | c='\t')
状态=输出;
else if(state==OUT){
状态=IN;
++西北;
}
}
printf(“%d\n”,nw);
}
这本书中有一个函数示例:“Brian W Kernighan和Dennis M Ritchie:Ansi C编程语言”。正如作者所说:这是UNIX程序wc的基本版本。更改为仅计算单词如下:
#include <stdio.h>
#define IN 1 /* inside a word */
#define OUT 0 /* outside a word */
/* nw counts words in input */
main()
{
int c, nw, state;
state = OUT;
nw = 0;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}
printf("%d\n", nw);
}
#包括
#在1/*中定义一个单词*/
#在单词外定义0/**/
/*nw统计输入中的单词数*/
main()
{
州西北部国际中心;
状态=输出;
nw=0;
而((c=getchar())!=EOF){
如果(c=''| | c='\n'| | c='\t')
状态=输出;
else if(state==OUT){
状态=IN;
++西北;
}
}
printf(“%d\n”,nw);
}
您可以执行以下操作:
int count()
{
unsigned int cCount = 0, wCount = 0, lCount = 0;
int incr_word_count = 0;
char c;
FILE *fp = fopen ("text", "r");
if (fp == NULL)
{
printf ("Failed to open file\n");
return -1;
}
while((c = fgetc(fp)) != EOF)
{
cCount++; // character count
if(c == '\n') lCount++; // line count
if (c == ' ' || c == '\n' || c == '\t')
incr_word_count = 0;
else if (incr_word_count == 0) {
incr_word_count = 1;
wCount++; // word count
}
}
fclose (fp);
printf ("line : %u\n", lCount);
printf ("word : %u\n", wCount);
printf ("char : %u\n", cCount);
return 0;
}
你可以做:
int count()
{
unsigned int cCount = 0, wCount = 0, lCount = 0;
int incr_word_count = 0;
char c;
FILE *fp = fopen ("text", "r");
if (fp == NULL)
{
printf ("Failed to open file\n");
return -1;
}
while((c = fgetc(fp)) != EOF)
{
cCount++; // character count
if(c == '\n') lCount++; // line count
if (c == ' ' || c == '\n' || c == '\t')
incr_word_count = 0;
else if (incr_word_count == 0) {
incr_word_count = 1;
wCount++; // word count
}
}
fclose (fp);
printf ("line : %u\n", lCount);
printf ("word : %u\n", wCount);
printf ("char : %u\n", cCount);
return 0;
}
发布这些结果所基于的输入可能会有所帮助。你似乎认为一个词总是以空格结尾。如果它是输入的结尾、其他一些空白字符(如\t)或换行符,该怎么办?您可以发布输入文件的内容吗?fgetc不返回-1,它返回EOF。首先,您的代码将换行符后跟空格作为一个单词进行计数。您不计算行末的单词,也就是说,
Hello World\n
这一行将被计算为1行1字。发布这些结果所基于的输入可能会有所帮助。你似乎认为一个词总是以空格结尾。如果它是输入的结尾、其他一些空白字符(如\t)或换行符,该怎么办?您可以发布输入文件的内容吗?fgetc不返回-1,它返回EOF。首先,您的代码将换行符后跟空格作为一个单词进行计数。您不计算行末的单词,也就是说,如果(c=''c='\n'| c='\t')您将'\t'
分配给'\t'
给c
而不是公平性检查,则语句中的行将被计为1行1字。例如,我在一个编译的c可执行文件上运行它,我从这个程序得到的值与实际的wc不同。有什么想法吗?在我看来,这个程序设计用于处理文本文件中常见的“可读”ascii字符(包括制表符等)。如果在包含源代码的.c文件中运行它,它可能会给出与wc相同的答案。但在包含SOH、EOT、NUL等字符的编译文件中运行它可能会带来麻烦。例如,如果您使用记事本和记事本++打开一个已编译的文件,则可能是相同的。对于同一个文件,您将得到不同的结果(特殊字符打印方式不同)。我不建议在编译文件中使用它。在语句-中,如果(c==''c='\n'|c='\t')
您将'\t'
分配给c
而不是公平性检查。谢谢您的回答,但由于某些原因,此算法对某些文件不起作用。例如,我在一个编译的c可执行文件上运行它,我从这个程序得到的值与实际的wc不同。有什么想法吗?在我看来,这个程序设计用于处理文本文件中常见的“可读”ascii字符(包括制表符等)。如果在包含源代码的.c文件中运行它,它可能会给出与wc相同的答案。但在包含SOH、EOT、NUL等字符的编译文件中运行它可能会带来麻烦。例如,如果您使用记事本和记事本++打开一个已编译的文件,则可能是相同的。对于同一个文件,您将得到不同的结果(特殊字符打印方式不同)。我不建议在编译文件中使用它;用于检查c是空格还是notint isspace(int c);用于检查c是否为空格