使用streamreader读取.txt文件后写入控制台的文本仅部分显示

时间:2014-04-15 20:57:30

标签: c# streamreader

我试图在他们居住的城镇搜索存储在文本文件中的客户帐户。有三个客户帐户都有不同的城镇。我认为该程序找到了正确的客户,因为它确实返回数据写入屏幕但不是全部。这些图像更好地解释了它。试图嵌入他们但没有分数

文本文件内容:

enter image description here

当搜索住在利物浦的顾客时(虽然图像没有显示,但光标开始在DOB下面闪烁5行)

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

寻找贝尔法斯特客户。请注意,它会选择coreect DOB,但错误的客户编号和Surname。(我把评论中的链接赢了,并且让我发布超过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++;

                }

            }
    }

5 个答案:

答案 0 :(得分:5)

如果我是你,我会做的第一件事就是更好地理解StreamReader的工作方式。每次拨打ReadLine()时,您在文件中的位置都会提前另一行。我会重新考虑你的算法。也许有些东西:

  1. 读取文件中的所有行并在空行上拆分。
  2. 将非空行存储在包含所有信息的某种对象中。
  3. 搜索您的对象以找到您要查找的内容(例如:Town == Liverpool)。
  4. 如果您不了解如何阅读文件,尝试在阅读文件时执行此操作将变得困难。

    只是一个想法。 : - )

答案 1 :(得分:1)

你正在寻找包含城镇的线路,找到之后你会立即读下五行。但问题是你的信息出现在城镇之前,你需要阅读镇前的四条线路,和镇后的路线(日期)。

这是一种方法,但不是那么优雅。您可以使用临时列表来存储已知行,然后当您找到要查找的记录时,显示列表的前一项(行),如下所示: / p>

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

    }
}

您可以将此逻辑应用于您的代码.BTW,我还为您的while循环添加了另一个条件,以避免您拥有无限循环。 (!sr.EndOfStream)如果你到达流的末尾会破坏循环,如果你输入一个文件中不存在的城镇,那么你的循环将是无限,因为{{1永远不会改变。

这里的变化只是使用LINQ的另一种方式:

CityMatch

答案 2 :(得分: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要好得多,但我相信它可能会指向正确的方向。

答案 3 :(得分:1)

你的问题在于:

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

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

只有在您阅读了正确的城市名称后,才会生效。根据您的文件,这意味着您只会读取文件的最后一行,然后将其写入控制台。

另外,提供文件中未找到的名称将导致无限循环。

答案 4 :(得分: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 Mews Park”, 镇是“卡迪夫”, 镇是“03/07/1989”, 镇是“1001”, 镇是“科尔”, 镇是“乔”, 小镇是“10 Meadows”, 小镇是“贝尔法斯特”, 镇是“04/06/1969”, 镇是“1002”, 小镇是“Whilshere”, 小镇是“杰克”, 镇是“9主教流”, 镇是“利物浦”

请记住,每次ReadLine时文件指针都会被提前。

从输出截图中可以看出,只打印了最终记录的DOB。这是因为,如上所述,文件中的所有数据都已从流中消耗。

RecCount的最终值也将始终为1.在循环的每次迭代开始时将其重置为0.