首页 > 解决方案 > 与基本面斗争。尤其是 char[]、char* 和从数组中读取。也许我应该使用类型字符串

问题描述

我需要一点指导。

我想提高我的技能,所以我正在练习较小的项目。

当前的挑战是创建一个可以计算用户输入单词中的音节的函数

我的想法是声明一个元音数组:a、e、i、o、u。

然后遍历用户输入的单词,检查单词的任何字母是否与元音数组匹配,如果是,则检查下一个字母是否不匹配。(我假设音节是由元音和辅音的存在来定义的。)

这将需要嵌套的 for 循环,一个循环遍历单词,然后另一个循环遍历当前索引为“单词”的元音数组。

我什至还没有弄清楚我将如何为 word[i+1] 做同样的事情。

但是我很挣扎,因为由于基本错误,我无法编译我的程序。我可能应该使用字符串类,但我不知道。

这是我所拥有的(它不会编译!):

#include <iostream>

char vowels[] = {'a', 'e', 'i', 'o', 'u'};

int numberOfSyllables(char *word)
{
    int numberOfVowelsFound = 0;

    for ( &element : word )
    {
        bool vowelMatch = 0;
        for ( &vowel : vowels)
        {
            if (element == vowel)
            {
                vowelMatch = 1;
                break;
            }
        }
    if ((vowelMatch == 1) numberOfVowelsFound++;
    }
    return numberOfVowelsFound;
}


int main()
{
char *userInput[50];

std::cout << "Enter a word: ";
std::cin >> *userInput;

std::cout << numberOfSyllables(userInput) << " syllables found";

    return 0;
}

标签: c++arrayspointerschar

解决方案


这不是一个代码审查网站,但无论如何我都会尽力而为:

  1. 您的for循环没有类型:
    for (TYPE &element : word )

在这种情况下,您要循环的类型是char.

如果您希望编译器为您找出类型:

    for (auto &element : word)
  1. 您正在word使用“foreach”样式循环进行循环,但 achar *不能以这种方式循环。准确地说,没有为定义std::beginstd::end函数char *,因此“foreach”样式循环不知道您希望字符串从哪里开始/结束。要么使用不同样式的循环,要么使用支持“foreach”样式循环的类型(例如std::stringC++17's std::string_view)。

  2. (您在if语句中添加了一个额外的括号:

    //  |
    //  v
    if ((vowelMatch == 1) numberOfVowelsFound++;
  1. 您将userInput变量声明为“40 个指向字符的指针的数组”,但您可能希望向其写入“字符”,而不是“指向字符的指针”。将其类型更改为“40 个字符的数组”。

  2. 同样,您取消引用您的userInput变量(可能是为了避免警告),因为userInput它是一个“40 个数组(指向 char 的指针)”,将返回该数组中第一个未初始化的“指向 char 的指针”(*varvar[0]在这种情况下)。只需删除取消引用运算符*并按照上面的建议更改数组的类型,然后std::cin就会弄清楚该怎么做。因为您(错误地)userInput已经取消引用以避免警告,所以std::cin认为您想要写入未初始化指针指向的位置。此时,您也无法控制程序将在何处写入;它可能会简单地崩溃。

  3. 最后,您再次将错误的类型传递给numberOfSyllables(userInput),如前所述,userInput是“40 个指向 char 的指针的数组”,而您的函数需要一个“字符指针”。将类型更改userInput为“字符数组”,然后编译器可以将其转换为“字符指针”。

最终代码:

// compile with -std=c++17 for std::string_view, or use another loop style
#include <string_view>
#include <iostream>

char vowels[] = {'a', 'e', 'i', 'o', 'u'};

int numberOfSyllables(char *word)
{
    int numberOfVowelsFound = 0;

    // `std::string_view` can be used in "foreach" style loops
    // we need to use `const char`, since `std::string_view` is a "fake string" and not writable
    for (const char &element : std::string_view(word))
    // Another loop style (This even works in C):
    // for (int i=0; word[i] != '\0'; i++) // While the current element is not NUL
    // {
    //     const char element = word[i]; // Remember the current element
    {
        bool vowelMatch = 0;
        for (const char &vowel : vowels) // Use const here too just for good measure
        {
            if (element == vowel)
            {
                vowelMatch = 1;
                break;
            }
        }
        if (vowelMatch == 1) numberOfVowelsFound++; // Removed a parenthesis here
    }
    return numberOfVowelsFound;
}


int main()
{
    char userInput[50]; // Changed type of this variable

    std::cout << "Enter a word: ";
    std::cin >> userInput; // Removed a dereference here
    std::cout << numberOfSyllables(userInput) << " syllables found";

    return 0;
}

推荐阅读