【问题标题】:Read and return data from text file (C#)从文本文件中读取和返回数据 (C#)
【发布时间】:2015-11-09 19:49:37
【问题描述】:

我正在尝试制作一个程序来读取文本文件并从中返回数据(在本例中为货币)。文本文件以这种方式列出了所有货币:

USD US Dollars (USA)               1,077600 1,058100    1,097100
JPY Yen (Japan)                    133,080000   130,480000  135,680000
... etc.

所以当用户输入货币代码(比如日元)时,程序会打印:

JPY Yen (Japan)                    133,080000   130,480000  135,680000

然后,程序将循环并不断询问货币,直到用户输入一个空字符串。

这就是我现在拥有的:

using System;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using System.IO;

public class Currencies
{
    public static void Main()
    {
        string line;

        System.IO.StreamReader currencies = new System.IO.StreamReader("currencies.txt");

        Console.Write("Enter currency code >");
        string currency = Console.ReadLine();

        while ((line = currencies.ReadLine()) != null)
        {
                if (line.Contains(currency))
                {
                    Console.WriteLine(line);
                }
        }
        Console.ReadLine();
    }
}

现在,它返回正确的行,但循环在第一次输入后中断,如果输入一个空字符串,它会返回文本文件的每一行。

有什么想法可以继续制作吗?另外,我应该使用 ReadAllLines 而不是 StreamReader 吗?

【问题讨论】:

  • 您只要求提供一次货币代码,因此程序只会运行一次。用户无法输入另一个,因为他们从来没有机会输入。您需要在 while 循环中提示货币代码,并使用特定值来结束循环(例如,-1)。
  • 啊,对,我怎么没注意到。我将尝试将 Console.Write 粘贴在 while 循环中。
  • 你在哪里循环基于用户输入而不是货币文件?这就是我认为你的错误所在。
  • 另外,如果搜索的值为空字符串,String.Contains 将返回 true。请参阅返回值下的msdn.microsoft.com/en-us/library/dy85x1sa(v=vs.110).aspx
  • 您需要两个单独的 while 循环。提示用户输入的外部循环(直到用户输入将退出循环的值)和内部 while 循环来遍历每个输入的文件。

标签: c# file text streamreader


【解决方案1】:

ReadAllLines 与 StreamReader

如果您的文本文件真的很大,那么逐行扫描文件是一个好习惯。在任何其他情况下,ReadAllLines 将是更好的选择,尤其是在多次扫描时。

空字符串返回结果

您正在使用Contains 方法,该方法依次在字符串中搜索一个空字符串。 每个字符串在她的内部都有一个空字符串。

解决方案:测试以查看用户输入的任何空字符串,并以您认为合适的方式处理它。

只输入一次

您只搜索输入一次,而它无法猜测您希望它再次重新扫描。

解决方案:创建另一个循环,它将包裹当前循环,直到您需要它停止为止。

【讨论】:

【解决方案2】:

这应该以最有效的方式解决它:

   public static void Main()
    {

    string line;
    bool IsEmptyString = false;
    List<string> lines = new List<string>();
    using (System.IO.StreamReader currencies = new System.IO.StreamReader("currencies.txt")
    {
        while ((line = currencies.ReadLine()) != null)
        {
            lines.Add(line);
        }
    }

    while (!IsEmptyString)
    {
        string tempLine = "";
        Console.Write("Enter currency code >");
        string currency = Console.ReadLine();
        IsEmptyString = currency == "" ? true : false;
        tempLine = lines.FirstOrDefault(x => x.Contains(currency));
        if (tempLine!="")
         {
                Console.WriteLine(tempLine);
         }
        tempLine = "";

    }

}

【讨论】:

  • 这只会抓取输入中的第一行。如果该货币代码有多行怎么办?
  • 你需要它包含的所有结果吗?
  • 这是 OP 的问题。我只是在使用FirstOrDefault 指出一个潜在的陷阱。
  • 这个解决方案很好而且效率很高,但在我开始摆弄 ReadAllLines 而不是 StreamReader 之后,最终选择了另一个。
【解决方案3】:

您可以使用以下代码。内联解释

public static void Main()
{
    //read all lines from file only once, and keep for future use
    var currencyDetails = File.ReadAllLines(@"C:\YourDirectory\currencies.txt"); 

    string input = string.Empty;
    while (true) //keep looping until empty input by user
    {
        Console.Write("Enter currency code > ");
        input = Console.ReadLine();
        if (string.IsNullOrWhiteSpace(input)) //stop loop
            break;
        //from all lines of file, get the line where line starts with the user input e.g. usd
        var currencyDetail = currencyDetails.FirstOrDefault(l => l.StartsWith(input.ToUpper()));
        if (currencyDetail != null) //if a matching currency is found, show it
        {
            Console.WriteLine(currencyDetail);
        }
    }
    Console.ReadLine();
}

【讨论】:

  • 这只会抓取输入中的第一行。如果该货币代码有多行怎么办?
  • @Tim 从问题陈述来看,一种货币看起来很像只在一行中。如果 OP 另有说明,我会更新。
  • 这成功了。在我意识到使用 ReadAllLines 更好(文本文件不是那么大)之后,我实际上自己也想通了。非常感谢!
猜你喜欢
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
相关资源
最近更新 更多