2016-12-05 5 views
0

versuchen sollten, ein Bestandssystem in einer Konsolenanwendung zu vervollständigen, und ich bin daher auf diesem Teil fest, um sicherzustellen, dass ein Benutzer eine doppelte 8-stellige lange ID-Nummer nicht haben kann, Mein Problem ist wie folgt.Nicht alle Codepfade geben einen Wert zurück, wenn sie

Grundsätzlich bin ich mir nicht sicher, warum dieser Code nicht funktioniert, ich vermisse hier wahrscheinlich ein sehr offensichtliches Stück Code, Hilfe wäre willkommen, habe schon versucht Werte zu ändern, also mehr als wahrscheinlich einen Wert übersehen.

static int checkIDNumber(int ID) 
{ 
    // Check the number passed in & then loop through all the lines... 
    // If number is taken then output error, because id exists already 
    // Else allow the value to be used in the stock system. 

    int IDNumber = ID; 
    using (StreamReader sr = new StreamReader("Stockfile.txt")) 
    { 
     string lineValues; 

     while (sr.EndOfStream == false) 
     { 
      lineValues = sr.ReadLine(); 

      if (lineValues.Contains(IDNumber.ToString())) 
      { 
       Console.WriteLine("Id number is currently already taken."); 
      } 
      else 
      { 
       return IDNumber; 
      } 
     } 
    } 
} 

Ich gehe in meinem Wert von dieser Linie in einem anderen Verfahren, bei dem es im lokalen Bereich definiert ist.

stockID = checkIDNumber(stockID); 

Hier ist der vollständige Code:

class Program 
{ 
    static void Main(string[] args) 
    { 
     char menuOption = '0'; 

     while (menuOption != '3') 
     { 
      DisplayMenuOption(); 
      menuOption = GetMenuOption(); 

      switch (menuOption) 
      { 
       case '1': 
        AddStock(); 
        break; 

       case '2': 
        CheckStock(); 
        break; 

       case '3': 
        Console.WriteLine("Goodbye"); 
        break; 

       default: 
        Console.WriteLine("That is not a valid option"); 
        break; 

      } 
     } 


      // Keep it all happy for a screenshot ;) 
      Console.ReadLine(); 

    } 

    static void DisplayMenuOption() 
    { 
     Console.WriteLine("Do you wish to Add Stock(1) or Check Stock(2) or Exit(3)?"); 
    } 

    static void DisplayStockOption() 
    { 
     Console.WriteLine("Do you want to search by ID(1) or by Name(2), Delete current stock(3) or Exit(4)?"); 
    } 

    static char GetMenuOption() 
    { 

     char userChoice = '0'; 

     userChoice = Convert.ToChar(Console.ReadLine()); 
     return userChoice; 
    } 

    static void CheckStock() 
    { 
     char menuOption = 'a'; 
     while (menuOption != '4') 
     { 
      DisplayStockOption(); 
      menuOption = GetMenuOption(); 

      switch (menuOption) 
      { 
       case '1': 
        SearchID(); 
        break; 

       case '2': 
        SearchName(); 
        break; 

       case '3': 
        RemoveStock(); 
        break; 

       case '4': 
        Console.WriteLine("Goodbye"); 
        break; 

       default: 
        Console.WriteLine("That is not a valid option"); 
        break; 

      } 
     } 
    } 

    static void RemoveStock() 
    { 
     List<string> tempList = new List<string>(); 
     string lineValues = ""; 
     bool found = false; 
     int ID = 0; 

     using (StreamReader sr = new StreamReader("Stockfile.txt")) 
     { 

      Console.Write("Please enter the ID number to delete: "); 
      ID = Convert.ToInt32(Console.ReadLine()); 

      while (sr.EndOfStream == false) 
      { 
       lineValues = sr.ReadLine(); 

       if (lineValues.Contains(ID.ToString()) == false) 
       { 
        tempList.Add(lineValues); 
       } 
       else 
       { 
        found = true; 
       } 
      } 
     } 

     if (found == true) 
     { 
      using (StreamWriter sw = new StreamWriter("Stockfile.txt", false)) 
      { 
       for (int i=0; i < tempList.Count; i++) 
       { 
        sw.Write(tempList[i]); 
        sw.WriteLine(); 
       } 
      } 
     } 
    } 

    static void SearchName() 
    { 
     using (StreamReader sr = new StreamReader("Stockfile.txt")) 
     { 
      string name; 

      Console.Write("Please enter the name: "); 
      name = Console.ReadLine(); 


      while (sr.EndOfStream == false) 
      { 

       string lineValues = sr.ReadLine(); 

       if (lineValues.Contains(name)) 
       { 
        Console.WriteLine("{0}", lineValues); 
       } 
       else 
       { 
        Console.WriteLine("{0} does not exist in this stock system!",name); // Could try to match a similar string incase of spelling errors here, although after looking at it it may be a bit far for what is being required now, but in the real world application this would be a must else people would mistype words thus not having an exact match. 
       } 
      } 
     } 
    } 



     static void SearchID() 
    { 

     using (StreamReader sr = new StreamReader("Stockfile.txt")) 
     { 
      int IDNumber; 
      string lineValues; 

      Console.Write("Please enter the ID number: "); 
      IDNumber = Convert.ToInt32(Console.ReadLine()); 


      while (sr.EndOfStream == false) 
      { 

       lineValues = sr.ReadLine(); 

       if (lineValues.Contains(IDNumber.ToString())) 
       { 
        Console.WriteLine("{0}", lineValues); 
       } 
       else 
       { 
        Console.WriteLine("{0} does not exist in this stock system!", IDNumber); // Could try to match a similar string incase of spelling errors here, although after looking at it it may be a bit far for what is being required now, but in the real world application this would be a must else people would mistype words thus not having an exact match. 
       } 
      } 
     } 
    } 

    static int checkIDNumber(int ID) 
    { 
     // Check the number passed in & then loop through all the lines... 
     // If number is taken then output error, becuase id exists already 
     // Else allow the value to be used in the stock system. 


     using (StreamReader sr = new StreamReader("Stockfile.txt")) 
     { 
      int IDNumber; 
      string lineValues; 

      Console.Write("Please enter the ID number: "); 
      IDNumber = Convert.ToInt32(Console.ReadLine()); 


      while (sr.EndOfStream == false) 
      { 

       lineValues = sr.ReadLine(); 

       if (lineValues.Contains(IDNumber.ToString())) 
       { 
        Console.WriteLine("Id number is currently already taken."); 
       } 
       else 
       { 
        ID = IDNumber; 
        return ID; 
       } 
      } 
     } 


    } 

    static void AddStock(int IDNumber) 
    { 

     using (StreamWriter sw = new StreamWriter("Stockfile.txt", true)) 
     { 
      int stockID = 0; 
      int stockQuantity = 0; 
      double stockPrice = 0.00; 
      string stockName = ""; 
      string s = ""; // Being Lazy here, to convert to when needed. 

      while (stockID.ToString().Length != 8) 
      { 
       Console.Write("Please enter the stock ID number: "); 
       stockID = Convert.ToInt32(Console.ReadLine()); 

      } 

      s = stockID.ToString(); 
      sw.Write(s + "\t"); // Will only accept an 8 figure digit so is safe to have a single value here. 

      while (stockName.Length <= 2) // No fancy brands here...... 
      { 
       Console.Write("Please enter the name of the stock: "); 
       stockName = Console.ReadLine(); 
      } 

      s = stockName; 
      sw.Write(s + "\t"); 

      while (stockQuantity < 1) // Running a small shop here... 
      { 
       Console.Write("Please enter the quanity of stock: "); 
       stockQuantity = Convert.ToInt32(Console.ReadLine()); 
      } 

      s = stockQuantity.ToString(); 
      sw.Write(s + "\t"); 

      while (stockPrice < 0.01) // Running a very small shop.... 
      { 
       Console.Write("Please enter the price of the stock: "); 
       stockPrice = Convert.ToDouble(Console.ReadLine()); 
      } 

      s = stockPrice.ToString(); 
      sw.Write(s + "\t"); 

      sw.WriteLine(); // TO create the new line..... 

     } 

    } 
} 

}

+0

Nun, welchem ​​Wert kehren Sie in dem 'if (lineValues.Contains (IDNumber.ToString())) block? Was passiert auch, wenn die while-Schleife niemals ausgeführt wird? –

+0

Oder besser, wenn Ihre Dateien nur die gleiche ID enthalten? Der Compiler kann es nicht wissen und muss es nicht wissen.Sie haben eine Bedingung, die zum Funktionsexitpunkt führt, ohne dass ein Wert zurückgegeben wird. – Steve

+0

@Robertgold Eine Sache zu erkennen ist, dass die while-Schleife nur einmal ausgeführt wird (es sei denn, der erste Wert stimmt überein). Durch das Setzen der return-Anweisung in die while-Schleife wird verhindert, dass alle Zeilen im Stream fortgesetzt werden. –

Antwort

7

Das Problem ist, dass Sie nur einen Wert aus dem Inneren des else Block zurück.

Ihre Methode muss einen Wert zurückgeben, unabhängig davon, welchen Pfad das Programm durch Ihren Code einnimmt. Sie können dies auf verschiedene Arten beheben, abhängig von Ihren Anforderungen. Zum Beispiel können Sie einen "Catch-All" -Rückgabewert am Ende der Methode haben, so dass, wenn es alle Ihre Tests (dh if Blöcke) durchläuft und den unteren Rand erreicht, solange es ein sinnvolles Ergebnis ist, es zurückkehrt der Catch-All-Wert.

Alternativ könnten Sie einfach sicherstellen, dass Sie eine return Anweisung in jedem der Code-Pfade setzen. Dafür müssten Sie einen return im if Teil Ihres if Blockes hinzufügen, aber Sie würden wahrscheinlich auch noch eine Rückkehr außerhalb Ihrer while Schleife benötigen, da diese möglicherweise niemals ausgeführt wird.

Auch hier kommt es auf Ihre Bedürfnisse an.

+0

Also im Wesentlichen gibt es keine Möglichkeit, dies zu tun, ohne mehrere Return-Aussagen zu haben? Wie mir gesagt wurde, ist es eine schlechte Übung, sich daran zu gewöhnen, mehr als eine Rücksendeaussage zu haben. – Robertgold

+6

Sie können es mit einer Return-Anweisung tun. Die Vorgehensweise besteht darin, am Anfang der Methode eine Variable zu erstellen und sie an der Stelle festzulegen, an der sie definiert werden muss, und diese Variable dann am Ende der Methode zurückzugeben. Meiner Erfahrung nach ist es keine schlechte Praxis, mehrfache Ergebnisse zu erzielen, wenn der Code übersichtlicher und lesbarer wird und - wichtiger noch - weniger spröde oder fehleranfällig ist. –

3

Es ist zumindest logisch möglich, dass die Datei nur die ID enthält. Zum Beispiel, wenn ich „10“ als eine ID eingeben und die Datei ist:

10 
10 
10 
10 
... 

Es könnte der Fall sein, dass Sie wissen, dass das wird nie tatsächlich passieren, aber der Compiler kann nicht wirklich beweisen, dass es nicht geht. Aus der "Perspektive" des Compilers ergibt sich nicht wirklich ein Unterschied zwischen "kann passieren" und "kann nicht beweisen, dass es nicht passieren wird".

Auch Ihre Logik ist falsch. Wenn Sie wissen, dass der Benutzer eine doppelte ID angefordert hat, müssen Sie den Rest der Datei nicht überprüfen. Sie wissen bereits, dass es sich um ein Duplikat handelt.

Jetzt, wenn die erste Zeile der Datei nicht die ID ist, die sie angefordert haben, erlaubt es dem Benutzer, sie zu nehmen. Zum Beispiel, wenn der Benutzer aufgefordert „9“ als eine ID und die Datei wird wie folgt dar:

3 -- It only actually checks this line 
5 
9 -- Obviously the ID is already taken here but it'll never check this line 
2 
1 

Siehe meine Kommentare unter:

// I'd suggest making this "bool" - they already know what the ID number is, 
// so there's no point in returning it back to them 
static int checkIDNumber(int ID) 
{ 
    // Check the number passed in & then loop through all the lines... 
    // If number is taken then output error, because id exists already 
    // Else allow the value to be used in the stock system. 

    int IDNumber = ID; 
    using (StreamReader sr = new StreamReader("Stockfile.txt")) 
    { 

     string lineValues; 

     // In general, you shouldn't explicitly compare to "true" or "false." 
     // Just write this as "!sr.EndOfStream" 
     while (sr.EndOfStream == false) 
     { 

      lineValues = sr.ReadLine(); 

      if (lineValues.Contains(IDNumber.ToString())) 
      { 
       // In this case, you don't have to bother checking the rest of the file 
       // since you already know that the ID is taken 
       Console.WriteLine("Id number is currently already taken."); 

      } 
      else 
      { 
       // You actually can't return that at this point - you need to check 
       // the *entire* file before you conclude that it's not a duplicate 
       return IDNumber; 
      } 
     } 

    } 
} 
Verwandte Themen