2016-04-18 50 views
3

我正在寫一些代碼,並遇到了一些麻煩。我想寫一個函數來檢查一個字符串是否有元音,並試圖通過一個帶有switch語句的for循環來實現。顯然,它不起作用,並且由於某種原因從不返回真實。迭代通過一個字符串,並切換語句:C++

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語句,但我不能完全肯定,如果這就是原因所在。

任何想法?

+0

您的代碼是錯誤的。我會爲你修復它 – tomascapek

+0

你的循環計數器'i'應該是'std :: size_t'類型,因爲'userInp.size()'可能並不總是符合簽名的'int'。 – jotik

+0

另請注意,'return true;'語句後面的'break;'語句是死代碼,並且永遠不會執行。 – jotik

回答

1

問題是,如果有任何字符不是元音,那麼函數imediatelly返回false。也可以使用const &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; 
} 
+0

我不知道,仍然是C++的新手,所以我不熟悉它們所有的功能 – Panthy

+0

這是C函數,但它是純粹的設計。它會讓你省掉一些代碼。但definetelly查閱參考!如果你熟悉C和指針,那麼引用就是用C++方式的一種指針。 – tomascapek

+0

到目前爲止,我已經能夠與參考文件最接近的是&符號,但是對於我來說,這一點似乎更加複雜:P – Panthy

5

刪除此行從您的功能:

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; 
} 

但是,如果你不知道這意味着什麼,現在不擔心了,你的書或教程將介紹很快。

+0

我很困惑,假設我有一個字符串「Hello」,使用H作爲第一次迭代,在我的代碼中,它已經到了默認值並返回false,但是沒有break語句,所以不應該繼續執行代碼? – Panthy

+1

@Panthy不,一旦你'返回'你的函數結束,值(如果有的話)返回給調用者。 – nvoigt

+0

我看到...假設我有一個變量bool X,而不是返回true/false,我將true/false的值放入X中,最後將X退出循環,假設它會起作用嗎? – Panthy

13

我建議你抽取元音測試的邏輯到它自己的功能:

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); 
} 

(我將其更名爲scanStrcontains_vowel,因爲該名稱更具描述性。)

+0

compleeeeeeeeeeeetely丟在這裏,但我有點理解! – Panthy

+2

「字符串元音中的所有字符?」僅僅是「序列中的所有元素是否滿足某些謂詞?」的一個具體例子,而C++標準庫提供了一個算法。 – fredoverflow

+1

是促進解耦和使用std算法的唯一答案。更喜歡這個,請+1 –

0

首先,編譯器會將開關盒變成查找表,然後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; 
}