从输入中检测字符组合

时间:2013-01-29 03:15:08

标签: c

我的任务是:

编写一个程序,将输入读取到#并报告序列ei出现的次数。

我写了一些在大多数时候都有效的东西,但是当它有剂量时会有输入......

喜欢这个输入:(假设返回1)

sdlksldksdlskd
sdlsklsdks
sldklsdkeisldksdlk
#
number of combination is: 0

这是代码:

int main(void)

{
    int index = 0;
    int combinationTimes = 0;
    int total = 0;
    char userInput;
    char wordChar[index];

    printf("please enter your input:\n");

    while ((userInput = getchar()) != '#')
    {
        if (userInput == '\n')
            continue;

        wordChar[index] = userInput;
        index++;
        total++;
    }

    for (index = 1; index < total; index++)
    {
        if (wordChar[index] == 'i')
        {
            if (wordChar[--index] == 'e')
            {
                combinationTimes++;
                ++index;
            }
        }
    }

    printf("number of combination is: %d", combinationTimes);

    return 0;
}

请告诉我使用此输入我没有得到什么?

他在书中用“获得你的eieio奖”来测试它并且它有效...但是在我玩了一点之后我看到的并不总是这样。

2 个答案:

答案 0 :(得分:3)

似乎没有必要将文件读入数组。您只需跟踪在阅读ei或达到EOF之前找到#的次数:

#include <stdio.h>

int main(void)
{
    int c;
    int ei_count = 0;
    while ((c = getchar()) != EOF && c != '#')
    {
        if (c == 'e')
        {
            int c1 = getchar();
            if (c1 == 'i')
                ei_count++;
            else if (c1 != EOF)
                ungetc(c1, stdin);
        }
    }
    printf("ei appeared %d times\n", ei_count);
    return(0);
}

测试(该程序名为ei,由ei.c构建):

$ ei < ei.c
ei appeared 0 times
$ sed 1d ei.c | ei
ei appeared 1 times
$ sed 's/#/@/' ei.c | ei
ei appeared 4 times
$

第一个停在#include行,第二个停在比较中的#,第三个停止读取整个文件。它还为样本数据提供了正确的输出。


分析代码

您的主要问题是您没有为阵列分配任何空间。将数组的维度从index更改为4096.这对于您的测试目的而言足够大(但实际上程序应该注意数组而不是溢出它 - 但是我不会认为数组是必要的;请参阅上面的代码。

下一个主要问题是,getchar()尽管名称为int,但不是char。它可以返回任何有效字符加上不同的值EOF。所以它必须返回一个大于char的值。 (如果使用char,则会发生以下两种情况之一。如果char是签名类型,则一些有效字符 - 通常是ÿ,y-umlaut,U + 00FF,带有DIAERESIS的LATIN SMALL LETTER - 也是被视为EOF,即使它只是一个字符。如果char是无符号类型,则没有输入与EOF匹配。两者都不是正确的行为。)

修复这很容易,但是您的代码没有检测到EOF。始终处理EOF;数据可能格式错误。这是代码中的一个简单修复。

第三个问题是printf()语句不以换行符结尾;应该。

这里的测试条件很奇怪:

        if (wordChar[--index] == 'e')
        {
            combinationTimes++;
            ++index;
        }

使用一个预增量和一个后增量是很奇怪的,但这只是一个一致性问题。 更糟糕的是,当角色i出现在输入中并且前面没有e时会发生什么。考虑一下@include <stdio.h>行:您从index开始为1;这是一个i,所以你递减索引,但是wordChar[0]不是e,所以你不要再增加它,但是循环结束了,所以循环检查再次index 1,继续进行循环测试,i i @e长时间不是index

没有理由减少然后增加 if (wordChar[index-1] == 'e') combinationTimes++; ;只需使用:

#include <stdio.h>

int main(void)
{
    int index = 0;
    int combinationTimes = 0;
    int total = 0;
    int userInput;
    char wordChar[4096];

    printf("please enter your input:\n");

    while ((userInput = getchar()) != '#' && userInput != EOF)
    {
        if (userInput == '\n')
            continue;

        wordChar[index] = userInput;
        index++;
        total++;
    }
    printf("total: %d\n", total);

    for (index = 1; index < total; index++)
    {
        if (wordChar[index] == 'i')
        {
            if (wordChar[index-1] == 'e')
                combinationTimes++;
        }
    }

    printf("number of combination is: %d\n", combinationTimes);

    return 0;
}

修复后,您的代码就会运行。你遇到的麻烦很大程度上是因为你使用的数组不够大(大小为0),你用你正在阅读的数据覆盖了准随机存储器。

if

请注意,您可以合理地将嵌套 if (wordChar[index] == 'i' && wordChar[index-1] == 'e') combinationTimes++; 写为:

{{1}}

答案 1 :(得分:0)

更改wordChar数组值。

int main(void)

{
    int index = 0;
    int combinationTimes = 0;
    int total = 0;
    char userInput;
    //char wordChar[index]; // index = 0
    char wordChar[255]; // should change the value of array.

    printf("please enter your input:\n");

    while ((userInput = getchar()) != '#')
    {
        if (userInput == '\n')
            continue;

        wordChar[index] = userInput;
        index++;
        total++;
    }

    for (index = 1; index < total; index++)
    {
        if (wordChar[index] == 'i')
        {
            if (wordChar[--index] == 'e')
            {
                combinationTimes++;
                ++index;
            }
        }
    }

    printf("number of combination is: %d", combinationTimes);

    return 0;
}

或者您可以使用pointer,然后使用mallocrealloc