首页 > 解决方案 > 多字符常量警告

问题描述

我在使用多个 If else If 语句时遇到了麻烦......这是我到目前为止的代码,我需要做的就是询问小写元音和用户最喜欢的动物(猫或狗)。然后要求任何大写字母。请不要过分判断,但是当我运行我的代码时,我可以完美地回答元音,但它会回答最喜欢的动物部分,而不会让我输入猫或狗的输入。请帮助:c

int main()
{
    //set variables 
    char letter;
    
    //ask for lower case vowles 
    cout << "Give me a lowercase vowel - ";
    cin >> letter;
        
    //set vowles 
    if  (letter=='a' || letter=='e' ||  letter=='i' || letter=='o' || letter=='u' || letter=='y' )
    {
        cout << "Thank you! ";
    }
    else if  (letter=='A' || letter=='E' ||  letter=='I' || letter=='O' || letter=='U' || letter=='Y' )
    {
        cout << "Your stupid .... I said lowercase vowel.  ";
    }
    else 
    {
        cout <<  "Error Not A Vowel ";
    }
            
    //favorite animal
    cout << "what is your favorite animal? " << endl;
    
    //set animal 
    char animal;
    
    //if cat or dog good anything else bad 
    if  (animal == 'cat' || animal == 'Cat' || animal == 'dog' || animal == 'Dog' )
    {
        cout << " Omg I love that tooo!!! " ;
    }
    else  
    {
        cout << "Oh.. Thats your favorite animal ";
    }
    //any capital letter // pause its not working ... uh oh
        
    //end the program 
    cout << endl << endl;
    system("pause");
}                   

标签: c++

解决方案


如评论中所述,您混淆了字符和字符串。当 C++ 是您的第一语言时,这可能是一个痛点。Achar是单个字符,并用单引号括起来,例如
char letter = 'a';.

字符串可以由零到多个字符组成,并用双引号括起来。
std::string str = "Hello";

动物名称肯定是字符串而不是字符。C 字符串是一个特殊的字符数组这一事实通常会进一步混淆这一点。char str[] = "Hello";是有效代码,字符数组的元素是'H', 'e', 'l', 'l', 'o', '\0'.

代码'cat'只会在糟糕的时候结束。单引号表示一个字符,但您在其中填充了多个字符。在启用警告的情况下编译可能会发现这一点,-Wall -Wextra至少使用。

以下是最喜欢的动物部分的示例std::string

#include <cctype>
#include <iostream>
#include <string>

void string_to_lower(std::string& str) {
  for (auto& l : str) {
    l = std::tolower(static_cast<unsigned char>(l));
  }
}

int main() {
  std::string input;
  std::cout << "What's your favorite animal? ";
  std::getline(std::cin, input);

  string_to_lower(input);

  if (input == "cat" || input == "dog") {
    std::cout << "Cool.\n";
  } else {
    std::cout << "That's unfortunate.\n";
  }
}

一些输出:

~/tmp 
❯ ./a.out 
What's your favorite animal? CAT
Cool.

~/tmp 
❯ ./a.out 
What's your favorite animal? cAt
Cool.

~/tmp took 4s 
❯ ./a.out 
What's your favorite animal? axolotl
That's unfortunate.

请注意,通过在获取输入后将其小写,我只需要检查"cat"and "dog"并且我会发现所有可能的编写方式。您的代码错过了我使用的两个输入以及许多其他输入。

如果您不能使用std::string(我认为这很愚蠢),那么您使用 C 字符串的比较有点奇怪,而且代码通常有点笨拙。

#include <cctype>
#include <cstring>
#include <iostream>

void string_to_lower(char str[], int sz) {
  for (int i = 0; i < sz; ++i) {
    str[i] = std::tolower(static_cast<unsigned char>(str[i]));
  }
}

int main() {
  constexpr int strsz = 256;
  char input[strsz] = {0};
  std::cout << "What's your favorite animal? ";
  std::cin.getline(input, strsz - 1);

  // Unnecessary ternary, but it can catch issues and shorten the execution time
  // of the function
  string_to_lower(input, strlen(input) < strsz ? strlen(input) : strsz);

  if (!std::strcmp(input, "cat") || !strcmp(input, "dog")) {
    std::cout << "Cool.\n";
  } else {
    std::cout << "That's unfortunate.\n";
  }
}

一些输出:

~/tmp 
❯ ./a.out 
What's your favorite animal? CAT
Cool.

~/tmp 
❯ ./a.out 
What's your favorite animal? doG
Cool.

~/tmp took 6s 
❯ ./a.out 
What's your favorite animal? axolotl
That's unfortunate.

在这两个代码示例中,我使用getline方法而不是直接的std::cin. 通过这样做,我可以捕获多字输入,而不会让程序变得奇怪。请注意,我必须使用不同的方法来获取std::stringC 字符串的一行。

我最近还编辑了一些static_cast功能string_to_lower()。例如,如果有人试图输入重音字符或在英文字母表中找不到的字母,则需要它们来避免未定义的行为。从对该答案的评论中得出的一个结论应该是验证输入很困难,在 C++ 中更是如此,因为缺乏内置的支持。


推荐阅读