Search code examples
c#streamreader

Text written to Console after reading from .txt file using streamreader only partially appearing


I'm trying to search for a customer account stored in a text file by the town they live in. There are three customer accounts all with different towns. I think the program finds the correct customer as it does returns data to write to the screen but not all of it. These images explain it better. Tried to embed them but don't have the points

The text file contents:

enter image description here

When searching for the customer that lives in Liverpool(Although the image doesnt show it, the cursor starts blinking 5 lines below the DOB)

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

Searching for Belfast customer. Notice it picks up the coreect DOB but wrong customer number and Surname.(Ill put the link in the commentit won't let me post more than 2 links)

Heres the code of the method::

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

                }

            }
    }

Solution

  • You are searching for the line that contains the town, after you find it you read the next five lines immediately.But the problem is your informations comes before the town, you need to read the four line that comes before the town, and the line that comes after the town (date).

    Here is a way of doing this but not so elegant.You can use a temporary list to store readed lines then when you find the record that you are looking for display the previous items (lines) of the list like this:

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

    You can apply this logic to your code.BTW, I have also added another condition to your while loop in order to save you from having an infinite loop. (!sr.EndOfStream) that will break the loop if you reach the end of the stream, if you type a town that is not exists in your file then your loop will be infinite because CityMatch will never gonna change.

    Just for the variety here is another way using 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]);
    }