通过字符串进行循环,并切换语句:C++

Iterating through a string, and switch statements: C++

本文关键字:语句 C++ 字符串 循环      更新时间:2023-10-16

我正在写一些代码,遇到了一些麻烦。我想写一个函数来检查字符串是否有元音,并试图通过一个包含switch语句的for循环来完成。显然,由于某种原因,它不起作用,也永远不会变成真的。

bool scanStr(string userInp) {
    for (int i = 0; i < userInp.size(); i++) {
        switch (userInp[i])
        {
        case 'a':
        case 'A':
        case 'e':
        case 'E':
        case 'i':
        case 'I':
        case 'o':
        case 'O':
        case 'u':
        case 'U':
        case 'y':
        case 'Y':
            return true;
            break;
        default:
            return false;
        }
    }
}

我试着测试程序是否真的在字符串中迭代,结果确实如此,所以我不明白为什么在函数中,它总是返回false?

int main() {
    string userInp;
    string pigLatin;
    cout << "Please enter a string to convert to pig Latin: " << endl;
    cin >> userInp;
    cout << endl;
    // tests
    for (int i = 0; i < userInp.size(); i++) { //checking if it actually iterates
        cout << userInp[i];
    }
    cout << endl;
    if (scanStr(userInp))
        cout << "it has a vowel" << endl;
    else
        cout << "no vowel" << endl;
    system("pause");
    return 0;
}

起初,我认为这是因为即使在最后一个案例之后有一个break语句,循环仍在继续,但我不完全确定这是否是原因。

有什么想法吗?

我建议您将元音测试的逻辑提取到它自己的函数中:

bool is_vowel(char x)
{
    switch (x)
    {
    case 'a':
    case 'A':
    case 'e':
    case 'E':
    case 'i':
    case 'I':
    case 'o':
    case 'O':
    case 'u':
    case 'U':
    case 'y':
    case 'Y':
        return true;
    default:
        return false;
    }
}

然后你可以使用标准算法而不是循环:

#include <algorithm>
#include <string>
bool contains_vowel(const std::string& str)
{
    return std::any_of(str.begin(), str.end(), is_vowel);
}

(我将scanStr重命名为contains_vowel,因为这个名称更具描述性。)

从函数中删除以下行:

    default:
        return false;

它们使函数在遇到的第一个非元音上返回false

如果到达循环的结束并且还没有返回true,则只希望返回false

bool scanStr(string userInp) 
{
    for (int i = 0; i < userInp.size(); i++) 
    {
        switch (userInp[i])
        {
        case 'a':
        case 'A':
        case 'e':
        case 'E':
        case 'i':
        case 'I':
        case 'o':
        case 'O':
        case 'u':
        case 'U':
        case 'y':
        case 'Y':
            return true;
        }
    }
    return false;
}

现代C++中更好的方法是:

bool scanStr(const std::string& userInp) 
{
    for (const auto c : userInp) 
    {
        switch (c)
        {
        case 'a':
        case 'A':
        case 'e':
        case 'E':
        case 'i':
        case 'I':
        case 'o':
        case 'O':
        case 'u':
        case 'U':
        case 'y':
        case 'Y':
            return true;
        }
    }
    return false;
}

但如果你不知道这意味着什么,现在不要担心,你的书或教程很快就会解释。

问题是,如果任何字符不是元音,该函数会立即返回false。同时使用const &const允许您传递常量字符串,并且引用可以节省一些时间,因为C++不必复制整个字符串。

bool scanStr(const string & userInp) {
    for (int i = 0; i < userInp.size(); i++) {
        switch (userInp[i])
        {
        case 'a':
        case 'A':
        case 'e':
        case 'E':
        case 'i':
        case 'I':
        case 'o':
        case 'O':
        case 'u':
        case 'U':
        case 'y':
        case 'Y':
            return true;
            break;
        }
    }
    return false;
}

首先,编译器将开关情况转换为查找表,然后auto将由编译器根据分配的值(在本例中为char)确定为数据类型。

或者把它交给你的编译器,它知道如何做。

bool scanStr(string userInp)
{
    for(auto c : userInp)
    {
        switch (c)
        {
            case 'a': case 'A':
            case 'e': case 'E':
            case 'i': case 'I':
            case 'o': case 'O':
            case 'u': case 'U':
            case 'y': case 'Y':
            return true;
        }
    }
    return false;
}