查找字符串中两个连续元音的数量不起作用

时间:2010-07-11 20:38:57

标签: c string

当两个元音一个接一个地出现时,计数应该递增。但我不知道为什么它的增量超过了它。

#include<stdio.h>
#include<conio.h>
void main(void)
{       
    int i,j,count=0;
    char string[80];
    printf("Enter a string:\n");
    gets(string);
    for(i=0; ;i++)
    {
        if(string[i]=='\0')
            break;
        if(string[i]=='a'||string[i]=='A'||string[i]=='e'||string[i]=='E'||string[i]=='i'||string[i]=='I'||string[i]=='o'||string[i]=='O'||string[i]=='u'||string[i]=='U')
        {
            if(string[i+1]=='a'||string[i]=='A'||string[i]=='e'||string[i]=='E'||string[i]=='i'||string[i]=='I'||string[i]=='o'||string[i]=='O'||string[i]=='u'||string[i]=='U')
            count++;
        }
    }
    printf("%d",count);
    getch();
}

3 个答案:

答案 0 :(得分:5)

在这里看起来你有一个错字,你的代码:

if(string[i]=='a'||string[i]=='A'||string[i]=='e'||string[i]=='E'||string[i]=='i'||string[i]=='I'||string[i]=='o'||string[i]=='O'||string[i]=='u'||string[i]=='U')
{
    if(string[i+1]=='a'||string[i]=='A'||string[i]=='e'||string[i]=='E'||string[i]=='i'||string[i]=='I'||string[i]=='o'||string[i]=='O'||string[i]=='u'||string[i]=='U')
        count++;
}

注意第二个if语句,除了第一个条件之外的所有内容都是检查字符串[i]而不是字符串[i + 1]。所以如果你在string [i]中有'A',那么无论字符串[i + 1]是什么,这都会增加计数。

你想:

if(string[i]=='a'||string[i]=='A'||string[i]=='e'||string[i]=='E'||string[i]=='i'||string[i]=='I'||string[i]=='o'||string[i]=='O'||string[i]=='u'||string[i]=='U')
{
    if(string[i+1]=='a'||string[i+1]=='A'||string[i+1]=='e'||string[i+1]=='E'||string[i+1]=='i'||string[i+1]=='I'||string[i+1]=='o'||string[i+1]=='O'||string[i+1]=='u'||string[i+1]=='U')
        count++;
}

我还建议您查找函数tolower,这将使小写字符小写,这意味着您需要进行较少的比较,这将使此代码更易于阅读和维护。你也可以考虑在这里使用一个开关或任何数组,并可能编写一个辅助函数。

我想我无法忍受这段代码,这是一个更好的版本:

int is_vowel(char ch)
{
    switch (tolower(ch))
    {
    case 'a': case 'e': case 'i': case 'o': case 'u':
        return 1;
    default:
        return 0;
    }
}

然后制作你的if语句:

if (is_vowel(string[i]) && is_vowel(string[i+1]))
    count++;

看,更清洁,更容易阅读,你不觉得吗?

答案 1 :(得分:2)

您还有缓冲区溢出:

gets(string);

以下是糟糕的风格:

for(i=0; ;i++)
    {
        if(string[i]=='\0')
            break;

应该是

for(i=0; string[i]!='\0';i++)

答案 2 :(得分:0)

一次,尽可能地懒惰。如果你必须重复一部分代码,问问自己是否不能重复这样做。

我会这样做的:

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

const size_t MAX_LENGTH = 100;

//Counts the occurrences of two consecutive same characters
//in a string, without case
size_t cnt_doubled(char const * const str, int c) {
    size_t ret = 0;

    //A pointer browses the string until terminating char and
    //increments ret if the pointed char is the one seeked
    //two chars in a row
    for(char const *p = str ; *p != '\0' ; ++p) {
        ret += tolower(*p) == tolower(c) && tolower(*(p+1)) == tolower(c);
    }

    return ret;
}

//Explicit...
size_t cnt_doubled_vowels(char *str) {
    char const *vowels = "aeiouy";

    //A pointer browses the vowels and takes into account
    //the occurrences in the string of every char pointed
    size_t n_vowels = 0;
    for(char const *p = vowels ; *p != '\0' ; ++p) {
        n_vowels += cnt_doubled(str, *p);
    }

    return n_vowels;
}

int main(void) {
    //fgets returns a string terminated by a newline char (before
    //terminating char of course) but in your case it doesn't
    //matter
    char string[MAX_LENGTH] = "";
    fgets(string, MAX_LENGTH, stdin);

    printf("N : %d", cnt_doubled_vowels(string));

    return 0;
}