2013-01-15 41 views
3

嗨,你們在執行循環中的Y/N或y/n時會遇到一些麻煩。我設計的方式是用戶可以使用Y和N的大寫字母和小寫字母作爲循環中的答案。順便說一下,這裏是我的代碼,但似乎無法使其工作:Y/N或y/n在循環中

do 
     { 
      Console.WriteLine("\nSelect additional topping/s\n"); 

      Console.WriteLine("1 - Extra meat: 200"); 
      Console.WriteLine("2 - Extra cheese: 100"); 
      Console.WriteLine("3 - Extra veggies: 80\n"); 

      int selectedTopping = Convert.ToInt32(Console.ReadLine()); 

      switch (selectedTopping) 
      { 
       case 1: 
        pizza = new MeatToppings(pizza); 
        break; 

       case 2: 
        pizza = new CheeseToppings(pizza); 
        break; 

       case 3: 
        pizza = new VeggieToppings(pizza); 
        break; 

       default: 
        break; 
      } 

      Console.WriteLine("\nAdd more toppings? Y/N"); 


     } 

     while ((Console.ReadLine() == "Y") || (Console.ReadLine() == "y")); 
+2

應該不是你的'Pizza'類有一個'addToppings()'方法或澆頭的可公開訪問的列表?也許我今天沒有足夠的咖啡,但是你的代碼對我來說似乎沒有意義。 – dreamlax

+0

它不起作用? – DWright

+2

請記住,每次調用Console.ReadLine()時,程序都會等待用戶寫入內容並按Enter鍵。你有兩次,所以爲了繼續,用戶必須先輸入Y並按下回車鍵,然後輸入y並按下回車鍵。提拉克的答案提供了一個簡單的方法來做到這一點(你也可以投到更低的水平)。 – MasterMastic

回答

6
while ((Console.ReadLine() == "Y") || (Console.ReadLine() == "y")); 

這是要讀2條不同的線路,因爲你打電話ReadLine()兩次。您需要調用一次並保存值。

+0

這確實是O.P.代碼的一個關鍵問題,但是根據這些方面,Tilak的回答是一個可靠的解決方法。也就是說,將用戶輸入保存到變量中幾乎總是首選的方式。 – Devin

+1

@Devin事實上,蒂拉克的方式很好。我的個人風格是儘量避免這種事情,所以將輸入保存在變量中對我來說更具可讀性,並使代碼幾乎可以自行記錄。 –

+0

同意,良好的代碼應該是自我記錄(或至少我訂閱了這一理念)。 – Devin

6

您可以使用ToUpper

while ((Console.ReadLine().ToUpper() == "Y")); 
+5

使用ToUpper/ToLower的字符串比較應該不鼓勵。 [土耳其語問題和爲什麼你應該關心](http://haacked.com/archive/2012/07/05/turkish-i-problem-and-why-you-should-care.aspx) – Habib

+2

是的一般,但它不適用於這個問題。 'Y'沒有問題。這個問題帶有字符'i'。另外一個工具(FxCop或StyleCop)抱怨使用'ToLowerInvariant'來支持'ToUpperInvariant' – Tilak

6

嘗試使用String.EqualsStringComparison

String.Equals(Console.ReadLine(), "y", StringComparison.CurrentCultureIgnoreCase); 

從MSDN:

CurrentCultureIgnoreCase:使用文化敏感的排序規則比較字符串,當前的文化,並忽略被比較的字符串的情況。

OrdinalIgnoreCase:使用序號排序規則並忽略字符串的情況下,比較字符串進行比較。

5

要檢查Yy忽略的情況下,你應該使用string.Equals(string,StringComparison)超載。

while (Console.ReadLine().Equals("Y", StringComparison.InvariantCultureIgnoreCase)); 

請參閱The Turkish İ Problem and Why You Should Care使用ToUpperToLower與忽略大小寫字符串比較之前。

您當前的代碼正在從控制檯讀取兩行代碼,這就是爲什麼您的代碼保持第二個值的原因。

+0

這對於檢查一個甚至不受土耳其語框架影響的單個字符來說是矯枉過正的。瞭解土耳其套管等事情很重要,但知道其相關時機同樣重要。而這不是。 – dreamlax

+0

@dreamlax,它是如何過度殺傷?使用ToLower/ToUpper會創建一個新的字符串,我相信這是一個矯枉過正的問題。是的,土耳其語的套餐在這裏不是問題,但是對於忽略大小寫的字符串比較,'string.Equals'是一個好得多的方法 – Habib

+1

這太過分了,因爲它解決了一個不存在的問題,您已經過度地設計了需求。如果創建一個新的單字符字符串是應用程序性能的瓶頸,那麼我想你有一個問題。 – dreamlax

1

正如Austin剛剛指出的,您在while循環語句中使用了兩次ReadLine。

有一點值得一提的是試圖遵循模塊化的規則,這將有助於加快實施和調試我們的代碼。

自從我做了任何C#編程,所以sudo編碼這種Java風格已經有一段時間了。

由於它是命令行編程,您可能必須多次驗證用戶輸入。我要做的一件事是讓工具類包含常見的用戶輸入任務。

public class TerminalUtil { 
    private TerminalUtil() {} 

    public static boolean isYes(String msg){ return (msg.ToUpper() == "Y" || msg.ToUpper() == "YES"); } 
    public static boolean isNo(String msg){ return (msg.ToUpper() == "N" || msg.ToUpper() == "NO"); } 
    // You also might want basic conditionals to check if string is numeric or contains letters. 

    // I like using recursion for command line utilities so having a method that can re-print messages is handy 
    public static void display(String[] messages){ 
     for(String msg : messages){ 
      Console.WriteLine(msg); 
     } 
    } 

    public static boolean enterYesOrNo(String[] messages, String[] errorMessages){ 
     display(messages) 
     String input = Console.ReadLine(); 
     if(isYes(input)){ 
      return true; 
     } else if(isNo(input)){ 
      return false; 
     } else { 
      display(errorMessages); // Maybe something like, you didn't enter a yes or no value. 
      enterYesOrNo(messages, errorMessages); // Recursive loop to try again. 
     } 

    } 
} 

下面是代碼來訂購比薩餅可能是什麼樣子

public class OrderPizza{ 
    public static int selectToppings(){ 
     String[] message = new String[4]; 
     message[0] = ("\nSelect additional topping/s\n"); 
     message[1] = ("1 - Extra meat: 200"); 
     message[2] = ("2 - Extra cheese: 100"); 
     message[3] = ("3 - Extra veggies: 80\n"); 

     int option = TerminalUtils.entryNumeric(message, {"You entered an non-numeric character, try again"}); 
     if(option > 0 && option <= 3){ 
      return option; 
     } else { 
      Console.WriteLine("Number must be between 1 - 3, try again."); 
      return selectToppings(); 
     } 
    } 

    public static Pizza order(){ 
     Pizza pizza = new Pizza(); 

     while(true){ 
      int toppingCode = selectTopping(); 
      pizza.addTopping(toppingCode); 
      if(!TerminalUtil.enterYesOrNo({"\nAdd more toppings? Y/N"}, {"Please enter a 'Y'es or 'N'o"})){ 
       break; 
      } 
     } 
    } 
} 

這樣做的主要好處是,while循環的業務邏輯已經減少,那麼你可以在重用代碼TerminalUtils。這並不意味着一個優雅的解決方案,我很懶,這是凌晨3點的IRL,但它應該足以讓球滾動。

你應該重新考慮做的一件事是使用整數代碼來表示澆頭。使用枚舉可能會使事情更容易實現。

我還注意到,您添加了三種不同類型的比薩,我假設三個不同的對象。

由於您正在循環添加配料到披薩,因此需要製作一個抽象類的披薩。通過這種方式,您可以擴展通用的預製比薩餅,如意大利辣香腸或奶酪,如果您想要客戶定製他們的訂單,則可以使用抽象比薩類。

0

我沒有發現比更好的辦法:

while (str!="N") 
{ 
    str = Console.ReadLine(); 
    str = str.ToUpper(); 
    if (str == "Y"); 
     break; 
};