2016-12-05 2 views
0

콘솔 응용 프로그램에서 재고 시스템을 완료하려고 시도 했으므로 사용자가 중복 된 8 자리 긴 ID 번호를 가질 수 없도록이 부분을 고수했습니다. 내 문제는 다음과 같습니다.모든 코드 경로가 필요한 경우 값을 반환하지 않습니다.

기본적으로이 코드가 작동하지 않는 이유는 확실하지 않습니다. 여기서는 매우 분명한 코드 조각이 누락되어 도움을 받으실 수 있습니다. 값을 변경하려고 시도 했으므로 값을 간과 할 가능성이 있습니다.

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

로컬 범위에서 정의 된 다른 절차에서이 행의 값을 전달합니다.

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

글쎄, 당신은'경우에 반환하는 어떤 값 (lineValues.Contains (IDNumber.ToString()))'블록? while 루프가 실행되지 않는다면 어떻게 될까요? –

+0

파일에 동일한 ID 만 있으면 어떻게 될까요? 컴파일러는 알 필요가 없으며 알 필요가 없습니다.반환 할 값이없는 함수 종료 점으로 연결되는 조건이 있습니다. – Steve

+0

@Robertgold 인식해야 할 한 가지는 첫 번째 값이 일치하지 않는 한 while 루프가 한 번만 실행된다는 것입니다. return 문을 while 루프 내에두면 스트림의 모든 라인을 계속 통과하지 못하게됩니다. –

답변

7

문제는 당신은 단지 else 블록 내부에서 값을 반환하고 있다는 것입니다 :

stockID = checkIDNumber(stockID); 

여기에 전체 코드입니다.

프로그램에서 코드를 통과하는 경로에 관계없이 메서드에서 값을 반환해야합니다. 요구 사항에 따라 여러 가지 방법으로 문제를 해결할 수 있습니다. 예를 들어 메서드의 맨 아래에 "catch-all"반환 값을 가질 수 있으므로 모든 테스트 (예 : if 블록)를 통과하여 맨 아래에 도달하면 의미있는 결과가 반환되는 한 반환합니다. catch-all 값.

또는 각 코드 경로 내에 return 문을 넣어야합니다. 이를 위해서는 if 블록의 if 부분에 return을 추가해야하지만 결코 실행할 수 없으므로 while 루프 외부의 수익이 필요할 수도 있습니다.

다시 귀하의 요구에 따라 다릅니다.

+0

그래서 본질적으로 여러 개의 return 문을 사용하지 않고이 작업을 수행 할 수있는 방법은 없습니다. 내가 말했듯이, 하나 이상의 return 문을 쓰는 것에 익숙해지는 것은 나쁜 습관이다. – Robertgold

+6

return 문 하나만 사용하면됩니다. 당신이하는 방법은 메소드의 맨 위에 변수를 만들고, 그것을 설정해야하는 곳으로 변수를 설정 한 다음, 메소드의 끝에 변수를 반환하는 것입니다. 내 경험상, 코드가 간결하고 읽기 쉽고, 더 중요하게도 덜 부서 지거나 오류가 발생하기 쉬운 경우 여러 번 반환하는 것은 나쁜 습관이 아닙니다. –

3

최소한 논리적으로 파일에 ID 만 포함되어있을 수 있습니다.

10 
10 
10 
10 
... 

그것은 당신이 결코거야 실제로이 일어날 것을 알고있는 경우가 있습니다 만, 컴파일러는 정말 수 없습니다 : 내가 ID로 "10"를 입력하고 예를 들어, 파일은 그것이 실현되지 않을 것이라고을 증명하십시오. 컴파일러의 "관점"에서 "일어날 수있다"와 "일어날 수 없다는 것을 증명할 수 없다"는 차이가 없습니다.

또한 논리가 잘못되었습니다. 사용자가 중복 ID를 요청했다는 것을 알고 있다면 파일의 나머지 부분을 확인할 필요가 없습니다. 이미 중복 된 것으로 알고 있습니다.

파일의 첫 번째 줄이 요청한 ID가 아닌 경우 사용자가 가져올 수 있습니다. 사용자가 요청하는 경우 예를 들어, "9"다음 ID와 파일이됩니다 다음과 같음 :

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 

아래에있는 내 의견을 참조하십시오 :

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

    } 
}