C-计算文件中的字、字符和行。字符数
我必须用C写一个代码,输出给定文件中的字符数、行数和字数。这项任务似乎很简单,但我真的不确定在这一点上出了什么问题 下面是代码:C-计算文件中的字、字符和行。字符数,c,file,character,lines,words,C,File,Character,Lines,Words,我必须用C写一个代码,输出给定文件中的字符数、行数和字数。这项任务似乎很简单,但我真的不确定在这一点上出了什么问题 下面是代码: #include <stdio.h> #include <stdlib.h> #include <ctype.h> int main() { FILE *file; char filename[256]; char ch; char prevch; int lines=0; int
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main()
{
FILE *file;
char filename[256];
char ch;
char prevch;
int lines=0;
int words=0;
int characters=0;
printf("Enter your filename (don't forget about extension!):\n");
scanf("%s", filename);
file=fopen(filename, "r");
if(file == NULL)
{
printf("Cannot open file %s \n", filename);
exit(0);
}
else
{
while((ch=fgetc(file))!=EOF)
{
if(ch==' ' || ch=='\n' || ch=='\t')
{
if(isspace(prevch)==0)
{
words++;
}
}
if(ch=='\n')
{
lines++;
}
prevch=ch;
characters++;
}
}
fclose(file);
if(isspace(prevch)==0)
{
words++;
}
printf("Number of characters: %d\n", characters);
printf("Number of words: %d\n", words);
printf("Number of lines: %d\n", lines);
return 0;
}
#包括
#包括
#包括
int main()
{
文件*文件;
字符文件名[256];
char ch;
char-prevch;
int行=0;
int字=0;
整数字符=0;
printf(“输入文件名(别忘了扩展名!):\n”);
scanf(“%s”,文件名);
file=fopen(文件名为“r”);
if(file==NULL)
{
printf(“无法打开文件%s\n”,文件名);
出口(0);
}
其他的
{
而((ch=fgetc(文件))!=EOF)
{
如果(ch=''| | ch='\n'| | ch='\t')
{
如果(isspace(prevch)==0)
{
words++;
}
}
如果(ch='\n')
{
行++;
}
prevch=ch;
字符++;
}
}
fclose(文件);
如果(isspace(prevch)==0)
{
words++;
}
printf(“字符数:%d\n”,字符);
printf(“字数:%d\n”,字数);
printf(“行数:%d\n”,行);
返回0;
}
该任务的思想是输出应该与Linux中wc命令的输出相同。但我完全不知道为什么我的循环会跳过一些字符。我编写代码的方式应该适合计算每个字符,甚至是那些空白。为什么我的程序显示示例文件包含65个字符,而wc显示68个字符?我认为可能有一些字符被fgetc跳过,但这是不可能的,因为我以前在编写程序时使用过这个函数,将一个文本文件的内容复制到另一个文本文件,并且一切正常
顺便问一下,我的字数计算方法正确吗?循环后的条件应确保计算EOF前的最后一个字。我使用了isspace来确保结尾不仅仅是一些空格
谢谢
“我的程序显示示例文件包含65个字符,而wc显示68个字符” 您正在Windows上工作,并且您的文件只有三行吗?如果是这样,问题是Windows将CRLF行的结尾映射到换行符,因此3个CRLF对映射到3个换行符(仅限LF)的结尾,从而解释了差异。要解决此问题,请以二进制模式打开文件 在没有运行代码的情况下,我认为计算单词的代码还可以。您可以改为使用一个最初设置为0(false)的“in word”标志,并切换为true,当您在不在单词中的情况下检测到非空白的内容时,计算一个新词。两者都起作用;他们略有不同 另外,请记住
fgetc()
和亲戚返回的是int
,而不是char
。如果将返回值保存在char
中,则无法可靠地检测EOF,尽管问题的性质取决于纯char
是有符号的还是无符号的以及正在使用的代码集
如果plain
char
是无符号类型,则永远无法检测到EOF(因为EOF映射到0xFF,当它转换为int
以与EOF进行比较时,它是正值)。如果明文char
有符号,如果输入包含代码0xFF(在ISO 8859-1和相关代码集中,即Unicode术语中的带分音符的ÿ-拉丁文小写字母Y),则可以提前检测到EOF。但是,有效的UTF-8永远不能包含字节0xFF(也不能包含0xC0、0xC1或0xF5..0xFF),因此您不应该遇到这种误解问题-但是您的代码是字节计数而不是字符计数。您可以这样做
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main()
{
FILE *file;
char filename[256];
char ch;
char prevch = '\0';
int lines = 0;
int words = 0;
int characters = 0;
printf("Enter your filename (don't forget about extension!):\n");
scanf("%s", filename);
file = fopen(filename, "r");
if(file == NULL)
{
fprintf(stderr, "Cannot open file %s \n", filename);
exit(-1);
}
while((ch = fgetc(file)) != EOF)
{
if(isspace(ch))
{
if (ch == '\n')
lines++;
}else {
if (prevch == '\0' || isspace(prevch))
words++;
}
characters++;
prevch = ch;
}
fclose(file);
printf("Number of characters: %d\n", characters);
printf("Number of words: %d\n", words);
printf("Number of lines: %d\n", lines);
return 0;
}
#包括
#包括
#包括
int main()
{
文件*文件;
字符文件名[256];
char ch;
char prevch='\0';
int行=0;
int字=0;
整数字符=0;
printf(“输入文件名(别忘了扩展名!):\n”);
scanf(“%s”,文件名);
file=fopen(文件名为“r”);
if(file==NULL)
{
fprintf(stderr,“无法打开文件%s\n”,文件名);
出口(-1);
}
而((ch=fgetc(文件))!=EOF)
{
if(isspace(ch))
{
如果(ch='\n')
行++;
}否则{
if(prevch='\0'| | isspace(prevch))
words++;
}
字符++;
prevch=ch;
}
fclose(文件);
printf(“字符数:%d\n”,字符);
printf(“字数:%d\n”,字数);
printf(“行数:%d\n”,行);
返回0;
}
if(ch='''.\124; ch=''\n'.\124; ch='\t')
为什么不也使用isspace(ch)
?您还没有初始化prevch-您应该初始化它以包含一个空格,否则如果文件中的第一个字符是空格,您的计数就不正确……请记住:fgetc()
返回一个int
,而不是char
。如果使用char
,则无法可靠地检测到EOF,尽管问题的性质取决于普通char
是有符号的还是无符号的,以及正在使用的代码集。“我的程序显示示例文件包含65个字符,而wc
显示68个字符”:您在Windows上工作吗?您的文件只有三行吗?如果是这样,问题是Windows将CRLF行的结尾映射到换行符,因此3个CRLF对映射到3个NL only(LF only)结尾,从而导致差异。以二进制模式打开文件。@Coolerini WIndows上的CRLF行结束与Linux/Unix上的LF行结束等是一个非常常见的问题。