我正在尝试编写一个程序来计算文本中的字符,单词和行数,文本为:
It was a dark and stormy night;
the rain fell in torrents - except
at occasional intervals, when it was
checked by a violent gust of wind
which swept up the streets (for it is
in London that our scene lies),
rattling along the housetops, and fiercely
agitating the scanty flame of the lamps
that struggled against the darkness.
Edward Bulwer-Lytton's novel Paul Clifford.
我不断收到62
而不是64
,有什么建议吗?
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
int main() {
int tot_chars = 0; /* total characters */
int tot_lines = 0; /* total lines */
int tot_words = 0; /* total words */
int boolean;
/* EOF == end of file */
int n;
while ((n = getchar()) != EOF) {
tot_chars++;
if (isspace(n) && !isspace(getchar())) {
tot_words++;
}
if (n == '\n') {
tot_lines++;
}
if (n == '-') {
tot_words--;
}
}
printf("Lines, Words, Characters\n");
printf(" %3d %3d %3d\n", tot_lines, tot_words, tot_chars);
// Should be 11 64 375
// rn is 11 65 375
return 0;
}
答案 0 :(得分:2)
您的代码中存在多个问题:
if (isspace(n) && !isspace(getchar()))
中,您可能会从文件中消耗一个字节而无法递增tot_chars
,此外,如果2个单词由2个空格字符分隔,则不会增加tot_words
。这会导致darkness.
和Edward
被计为一个单词。当您看到连字符时递减tot_words
,这是不正确的,因为单词仅由空格分隔。这会导致Bulwer-Lytton's
计为1-1
,即为零。因此,你只能获得62个单词而不是64个单词。
在较小的注释中,名称n
对从文件读取的字节感到困惑。它通常是一个更合适的计数名称。从文件读取的字节的惯用名称为c
,类型正确为int
,以适应unsigned char
的所有值加上特殊值EOF
。< / p>
要检测字边界,您应该使用状态并在状态更改时更新字数:
#include <ctype.h>
#include <stdio.h>
int main(void) {
int tot_chars = 0; /* total characters */
int tot_lines = 0; /* total lines */
int tot_words = 0; /* total words */
int in_space = 1;
int c, last = '\n';
while ((c = getchar()) != EOF) {
last = c;
tot_chars++;
if (isspace(c)) {
in_space = 1;
if (c == '\n') {
tot_lines++;
}
} else {
tot_words += in_space;
in_space = 0;
}
}
if (last != '\n') {
/* count last line if not linefeed terminated */
tot_lines++;
}
printf("Lines, Words, Characters\n");
printf(" %3d %3d %3d\n", tot_lines, tot_words, tot_chars);
return 0;
}
答案 1 :(得分:0)
以下两个条件都会增加换行符的字数,这意味着每个单词后跟换行而不是空格会被计算两次:
if (isspace(n) || n == '\n'){
tot_words++;
}
if (n=='\n'){
tot_lines++;
tot_words++;
}
如果你摆脱|| n == '\n'
位,你应该得到正确的计数。
答案 2 :(得分:0)
更改
if (n=='\n'){
tot_lines++;
tot_words++;
}
到
if (n=='\n'){
tot_lines++;
}
您已在
中的新行计算单词 if (isspace(n) || n == '\n'){
tot_words++;
}
因此,你有效地将字计数器递增一次,而不是每行所需。
答案 3 :(得分:0)
实际上现在我认为你必须修改程序,假设单词用空格分隔(任何其他空格字符),如果你的文本有两个或多个空格(任何其他空白字符),则对这个基数的计数将不起作用分开一个单词。因为这也将被视为单词,(当没有使用实际单词时)
我认为您的上一个if
块非常混乱,您使用ispunct()
递减tot_words
,但您的文字中的单词使用了标点符号(不含空格),这意味着它们是文字的一部分。所以你不应该减少它们。
之前我认为我们应该只检查上一个-'
块中的'if
字符,因为它在带有空格的第一段文本中使用,但它也在新的名称中再次使用空间,所以我认为你应该完全忽略上一个if
块,并将'-'
视为简单逻辑的词。
我修改了第一个if块,即使在给出两个或多个空格(任何其他空格字符)来分隔单词时,它也会使程序出错。
if (isspace(n)) // isspace() checks for whitespace characters ' ', '\t', '\n','\r, so no need to write like this (isspace(n) || n == '\n')
boolean=0; //outside of word.
else if(boolean==0){
tot_words++;
boolean=1; //inside of word.
}
if (n=='\n')
tot_lines++;
答案 4 :(得分:0)
我检查你的代码,它工作正常,我也得到了输出(总字数),因为它希望 - 似乎代码已从其原始帖子
进行了编辑在运行代码后附加输出的内容 - 产量
答案 5 :(得分:0)
$ ./a.out " a b " "a b c " "a b c d"
s = a b , words_cnt= 2
s = a b c , words_cnt= 3
s = a b c d, words_cnt= 4
$ ./a.out "It was a dark and stormy night;
> the rain fell in torrents - except
......
Edward Bulwer-Lytton's novel Paul Clifford., words_cnt = 64
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int
count_words(const char *s)
{
int i, w;
for (i = 0, w = 0; i < strlen(s); i++)
{
if (!isspace(*(s+i)))
{
w++;
while (!isspace(*(s+i)) && *(s+i) != '\0')
{
i++;
}
}
}
return w;
}
int
main(int argc, const char *argv[])
{
int i;
if (argc < 2)
{
printf("[*] Usage: %s <str1> <str2> ...\n", argv[0]);
return -1;
}
for (i = 1; i < argc; i++)
{
printf("s = %s, words_cnt= %d\n ", argv[i], count_words(argv[i]));
}
return 0;
}