2014-04-15 84 views
4

我試圖通過他們居住的城鎮搜索存儲在文本文件中的客戶帳戶。有三個客戶帳戶都與不同的城鎮有關。我認爲程序找到了正確的客戶,因爲它確實返回數據寫入屏幕,但不是全部。這些圖像更好地解釋了它。試圖將它們嵌入,但沒有點使用流式閱讀器僅讀取部分文本的.txt文件後,寫入控制檯的文本

文本文件的內容:

enter image description here

當生活在利物浦客戶搜索(雖然圖像犯規表現出來,光標開始閃爍5線DOB下文)

http://i1370.photobucket.com/albums/ag266/Aaron_McCauley/2_zpsb6561828.png

搜索貝爾法斯特顧客。注意它拿起coreect DOB但不對客戶號碼和姓氏。(伊利諾伊放在commentit鏈接不會讓我上傳超過2個鏈接)

繼承人的方法::

static void FindTown(CustomerStruct[] CustomerDeats) 
    { 
     string City; 
     bool CityMatch = false; 
     Console.Clear(); 

    begin: 
     try 
     { 
      Console.WriteLine("Please enter the customers Town "); 
      City = Console.ReadLine();     
     } 
     catch 
     { 
      Console.WriteLine("Failed. Please try again."); 
      goto begin; 
     } 

     var pathToTown = @"..\..\..\Files\Customer.txt"; 

     using (StreamReader sr = new StreamReader(pathToTown)) 

      while (!CityMatch) 
      { 

       { 
        RecCount = 0; 

        CustomerDeats[RecCount].Town = sr.ReadLine(); 

        if (City == CustomerDeats[RecCount].Town) 
        { 

         Console.WriteLine("\n\n"); 

         CityMatch = true; 



         CustomerDeats[RecCount].CustomerNo = sr.ReadLine(); 
         Console.WriteLine(CustomerDeats[RecCount].CustomerNo); 

         CustomerDeats[RecCount].Surname = sr.ReadLine(); 
         Console.WriteLine(CustomerDeats[RecCount].Surname); 

         CustomerDeats[RecCount].Forename = sr.ReadLine(); 
         Console.WriteLine(CustomerDeats[RecCount].Forename); 

         CustomerDeats[RecCount].Street = sr.ReadLine(); 
         Console.WriteLine(CustomerDeats[RecCount].Street); 

         CustomerDeats[RecCount].Town = sr.ReadLine(); 
         Console.WriteLine(CustomerDeats[RecCount].Town); 

         CustomerDeats[RecCount].DOB = sr.ReadLine(); 
         Console.WriteLine(CustomerDeats[RecCount].DOB); 

         Console.ReadKey(); 


        } 

        RecCount++; 

       } 

      } 
    } 
的代碼
+0

http://i1370.photobucket.com/albums/ag266/Aaron_McCauley/3_zpsc6e9e525.png – COYG

+2

在任何現代編程語言中使用'goto'很少是個好主意。它會導致難以理解和維護的非結構化代碼。 –

+0

我會記住這一點,並確保我熟悉它。 – COYG

回答

1

您正在尋找包含城鎮的線路,發現後立即閱讀下面五行。但問題是您的信息出現在城鎮之前,您需要閱讀城鎮前的四條線路,以及在鎮(日期)之後的線。

這是做這件事的一種方式,但不是那麼優雅。您可以使用臨時列表來存儲相關行,然後當您找到您正在查找的記錄時,會顯示列表中的以前的項目(行),如下所示:

using (StreamReader sr = new StreamReader(pathToTown)) 
{ 
    var tempLines = new List<string>(); 
    while (!CityMatch && !sr.EndOfStream) 
    { 

     string line = sr.ReadLine(); 

     if (City == line) 
     { 
      Console.WriteLine("\n\n"); 
      CityMatch = true; 
      int count = tempLines.Count; 
      Console.WriteLine("Customer No: {0}", tempLines[count-4]); 
      Console.WriteLine("Customer Surname: {0}", tempLines[count - 3]); 
      Console.WriteLine("Customer Forename: {0}", tempLines[count - 2]); 
      Console.WriteLine("Customer Street: {0}", tempLines[count - 1]); 
      Console.WriteLine("Customer Town: {0}", line); 
      Console.WriteLine("Customer Day Of Birth: {0}", sr.ReadLine()); 
      Console.ReadKey(); 

     }else tempLines.Add(line); 

    } 
} 

你可以把這個邏輯在code.BTW,我也爲了節省您從具有無限循環中添加另一個條件你while循環。 (!sr.EndOfStream),如果你到達流的末尾,將打破循環,如果你鍵入一個不存在於你的文件中的城鎮,那麼你的循環將是無限,因爲CityMatch永遠不會改變。

只爲這裏的品種是用LINQ另一種方式:

var town = Console.ReadLine(); 
var record = File.ReadLines("filepath") 
       .Where(x => x != string.Empty) 
       .Select((line, idx) => new {line, idx}) 
       .GroupBy(x => x.idx/6) 
       .FirstOrDefault(x => x.Any(e => e.line.Contains(town))); 

if (record != null) 
{ 
    var values = record.Select(x => x.line).ToArray(); 
    Console.WriteLine("Customer No: {0}", values[0]); 
    Console.WriteLine("Customer Surname: {0}", values[1]); 
    Console.WriteLine("Customer Forename: {0}", values[2]); 
    Console.WriteLine("Customer Street: {0}", values[3]); 
    Console.WriteLine("Customer Town: {0}", values[4]); 
    Console.WriteLine("Customer Day Of Birth: {0}", values[5]); 
} 
+0

我明白你的意思了,一旦找到了這個城市,我該如何告訴程序返回四行? – COYG

+0

@ user3536292我會在一分鐘內更新我的答案 –

+0

非常感謝! – COYG

1

你開始讀取客戶的數據時,讀寫器到達一個城市,但城市後有1個記錄的領域去。考慮先將所有數據讀入內存。例如 - 進入數組。事情是這樣的:

string s = File.ReadAllText(pathToTown).Trim(); 
string[] customersUnparsed = s.Split(new[] { Environment.NewLine + Environment.NewLine }, 
    StringSplitOptions.RemoveEmptyEntries); 
string[][] customers = Array.ConvertAll(customersUnparsed, 
    c => c.Split(new[] { Environment.NewLine }, StringSplitOptions.None)); 

用例:

string[] customer = Array.Find(customers, c => c[4] == "Liverpool"); 

這段代碼不夠完善。我意識到爲客戶創建classstruct要好得多,但我相信這可能會指向您正確的方向。

+0

「ReadAllText」有什麼意義?你可以使用'File.ReadLines'並篩選我知道的空行 –

+0

,但使用雙'Environment.NewLine'分割要容易得多。 – Dmitry

1

你的問題就出在這裏:

CustomerDeats[RecCount].Town = sr.ReadLine(); 

if (City == CustomerDeats[RecCount].Town) 

的,如果一旦你已經在正確的城市名稱讀只會是真實的。根據您的文件,這意味着您只會讀取文件的最後一行,然後將其寫入控制檯。

另外,提供文件中找不到的名稱將導致無限循環。

5

如果我是你,我會做的第一件事就是更好地理解StreamReader的工作方式。每當您撥打ReadLine()時,您在該文件中的位置將推進另一行。我會重新考慮你的算法。也許沿着這樣的路線:

  1. 讀取文件中的所有行,並在空行上分割。
  2. 將非空行存儲在某種包含所有信息的對象中。
  3. 通過你的對象搜索找到你要找的東西(例如:鎮==利物浦)。

如果您不理解讀取文件的方式,嘗試在讀取文件時執行此操作會變得困難。

只是一個想法。 :-)

+0

將採取的船上,歡呼! – COYG

0

如果用戶輸入的單詞不在文件中,首先警告您的代碼將進入無限循環。在你的例子中,它是利物浦你也需要檢查EndOfStream。 http://msdn.microsoft.com/en-us/library/vstudio/system.io.streamreader.endofstream

ReadLine方法讀取一行並前進指針。 http://msdn.microsoft.com/en-us/library/vstudio/system.io.streamreader.readline

在你的示例代碼是什麼被讀入屬性鎮,直到它遇到利物浦。這是在每一個讀入城鎮的線路。

鎮是「1000」, 鎮「拉姆齊」, 鎮是「阿龍」, 鎮「10馬廄公園」, 鎮是「夫」, 鎮是「1989年3月7日」 , 鎮是「1001」, 鎮是「科爾」, 鎮是「喬」, 鎮是「10草甸」, 鎮是「貝爾法斯特」, 鎮是「1969年4月6日」, 鎮是「1002」, 鎮是「Whilshere」, 鎮是「傑克」, 鎮是「9 Bishop小河」, 鎮是「利物浦」

請記住,每次您ReadLine時文件指針都在高級。

正如你所看到的那樣,輸出截圖只顯示最終記錄的DOB。這是因爲,如上所示,文件中的所有數據都已從流中消耗。

此外,RecCount的最終值將始終爲1.在循環的每次迭代開始時將其重置爲0。