从 C# 中的文本文件中读取数字

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1968328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:17:22  来源:igfitidea点击:

Read numbers from a text file in C#

c#filetext

提问by Joe

This is something that should be very simple. I just want to read numbers and words from a text file that consists of tokens separated by white space. How do you do this in C#? For example, in C++, the following code would work to read an integer, float, and word. I don't want to have to use a regex or write any special parsing code.

这应该是非常简单的事情。我只想从由空格分隔的标记组成的文本文件中读取数字和单词。你如何在 C# 中做到这一点?例如,在 C++ 中,以下代码将用于读取整数、浮点数和单词。我不想使用正则表达式或编写任何特殊的解析代码。

ifstream in("file.txt");
int int_val;
float float_val;
string string_val;
in >> int_val >> float_val >> string_val;
in.close();

Also, whenever a token is read, no more than one character beyond the token should be read in. This allows further file reading to depend on the value of the token that was read. As a concrete example, consider

此外,无论何时读取令牌,都不应读入超过令牌的一个字符。这允许进一步的文件读取取决于读取的令牌的值。作为一个具体的例子,考虑

string decider;
int size;
string name;

in >> decider;
if (decider == "name")
    in >> name;
else if (decider == "size")
    in >> size;
else if (!decider.empty() && decider[0] == '#')
    read_remainder_of_line(in);

Parsing a binary PNM file is also a good example of why you would like to stop reading a file as soon as a full token is read in.

解析二进制 PNM 文件也是一个很好的例子,说明为什么在读入完整令牌后立即停止读取文件。

采纳答案by Jon Skeet

Brannon's answer explains how to read binarydata. If you want to read textdata, you should be reading strings and then parsing them - for which there are built-in methods, of course.

Brannon 的回答解释了如何读取二进制数据。如果你想读取文本数据,你应该读取字符串然后解析它们——当然,有内置的方法。

For example, to read a file with data:

例如,要读取包含数据的文件:

10
10.5
hello

You might use:

你可能会使用:

using (TextReader reader = File.OpenText("test.txt"))
{
    int x = int.Parse(reader.ReadLine());
    double y = double.Parse(reader.ReadLine());
    string z = reader.ReadLine();
}

Note that this has no error handling.In particular, it will throw an exception if the file doesn't exist, the first two lines have inappropriate data, or there are less than two lines. It will leave a value of nullin zif the file only has two lines.

请注意,这没有错误处理。特别是,如果文件不存在,前两行有不合适的数据,或者少于两行,它会抛出异常。如果文件只有两行,它将保留值nullin z

For a more robust solution which can fail more gracefully, you would want to check whether reader.ReadLine()returned null(indicating the end of the file) and use int.TryParseand double.TryParseinstead of the Parsemethods.

对于可以更优雅地失败的更健壮的解决方案,您需要检查是否reader.ReadLine()返回null(指示文件结尾)并使用int.TryParseanddouble.TryParse代替Parse方法。

That's assuming there's a line separator between values. If you actually want to read a string like this:

那是假设值之间有一个行分隔符。如果您确实想读取这样的字符串:

10 10.5 hello

then the code would be very similar:

那么代码将非常相似:

using (TextReader reader = File.OpenText("test.txt"))
{
    string text = reader.ReadLine();
    string[] bits = text.Split(' ');
    int x = int.Parse(bits[0]);
    double y = double.Parse(bits[1]);
    string z = bits[2];
}

Again, you'd want to perform appropriate error detection and handling. Note that if the file really just consisted of a single line, you may want to use File.ReadAllTextinstead, to make it slightly simpler. There's also File.ReadAllLineswhich reads the whole file into a string array of lines.

同样,您需要执行适当的错误检测和处理。请注意,如果文件真的只由一行组成,您可能想要使用File.ReadAllText它,使其稍微简单一些。还有File.ReadAllLines将整个文件读入行的字符串数组。

EDIT: If you need to split by anywhitespace, then you'd probably be best off reading the whole file with File.ReadAllTextand then using a regular expression to split it. At that point I do wonder how you represent a string containing a space.

编辑:如果你需要用任何空格分割,那么你最好阅读整个文件,File.ReadAllText然后使用正则表达式来分割它。那时我确实想知道您如何表示包含空格的字符串。

In my experience you generally know more about the format than this - whether there will be a line separator, or multiple values in the same line separated by spaces, etc.

根据我的经验,您通常比这更了解格式 - 是否会有行分隔符,或同一行中的多个值由空格等分隔。

I'd also add that mixed binary/text formats are generally unpleasant to deal with. Simple and efficient text handling tends to read into a buffer, which becomes problematic if there's binary data as well. If you need a text section in a binary file, it's generally best to include a length prefix so that just that piece of data can be decoded.

我还要补充一点,混合的二进制/文本格式通常很难处理。简单而高效的文本处理往往会读入缓冲区,如果还有二进制数据,这就会成为问题。如果您需要二进制文件中的文本部分,通常最好包含一个长度前缀,以便只对那段数据进行解码。

回答by Brannon

using (FileStream fs = File.OpenRead("file.txt"))
{
    BinaryReader reader = new BinaryReader(fs);

    int intVal = reader.ReadInt32();
    float floatVal = reader.ReadSingle();
    string stringVal = reader.ReadString();
}

回答by jrbalderrama

Try someting like this:

尝试这样的事情:

http://stevedonovan.blogspot.com/2005/04/reading-numbers-from-file-in-c.html

http://stevedonovan.blogspot.com/2005/04/reading-numbers-from-file-in-c.html

IMHO Maybe to read a c# tutorial it will be really useful to have the whole picture in mind before asking

恕我直言,也许阅读 ac# 教程,在询问之前先考虑整个画面会非常有用

回答by Groo

Not exactly the answer to your question, but just an idea to consider if you are new to C#: If you are using a custom text file to read some configuration parameters, you might want to check XML serialization topics in .NET.

不完全是您问题的答案,只是您是否不熟悉 C# 时要考虑的一个想法:如果您使用自定义文本文件来读取某些配置参数,您可能需要查看 .NET 中的 XML 序列化主题。

XML serialization provides a simple way to write and read XML formatted files. For example, if you have a configuration class like this:

XML 序列化提供了一种简单的方法来编写和读取 XML 格式的文件。例如,如果您有这样的配置类:

public class Configuration
{
   public int intVal { get; set; }
   public float floatVal { get; set; }
   public string stringVal { get; set; }
}

you can simply save it and load it using the XmlSerializerclass:

您可以简单地保存它并使用XmlSerializer该类加载它:

public void Save(Configuration config, string fileName)
{
   XmlSerializer xml = new XmlSerializer(typeof(Configuration));
   using (StreamWriter sw = new StreamWriter(fileName))
   {
       xml.Serialize(sw, config);
   }
}

public Configuration Load(string fileName)
{
   XmlSerializer xml = new XmlSerializer(typeof(Configuration));
   using (StreamReader sr = new StreamReader(fileName))
   {
       return (Configuration)xml.Deserialize(sr);
   }
}

Savemethod as defined above will create a file with the following contents:

Save上面定义的方法将创建一个包含以下内容的文件:

<Configuration>
    <intVal>0</intVal>
    <floatVal>0.0</floatVal>
    <stringVal></stringVal>
</Configuration>

Good thing about this approach is that you don't need to change the Saveand Loadmethods if your Configurationclass changes.

这种方法的好处是,如果您的类发生变化,您无需更改SaveLoad方法Configuration

回答by Paul

I like using the StreamReader for quick and easy file access. Something like....

我喜欢使用 StreamReader 来快速轻松地访问文件。就像是....

  String file = "data_file.txt";    
  StreamReader dataStream = new StreamReader(file);   
  string datasample;
  while ((datasample = dataStream.ReadLine()) != null)
  {

     // datasample has the current line of text - write it to the console.
     Console.Writeline(datasample);
  }

回答by Ramashish Baranwal

C# doesn't seem to have formatted stream readers like C++ (I would be happy to be corrected). So Jon Skeet approach of reading the contents as string and parsing them to the desired type would be the best.

C# 似乎没有像 C++ 这样的格式化流阅读器(我很乐意得到纠正)。因此,Jon Skeet 将内容作为字符串读取并将它们解析为所需类型的方法将是最好的。

回答by GSoft Consulting

Here is my code to read numbers from the text file. It demonstrates the concept of reading numbers from text file "2 3 5 7 ..."

这是我从文本文件中读取数字的代码。它演示了从文本文件“2 3 5 7 ...”中读取数字的概念

public class NumberReader 
{
    StreamReader reader;

    public NumberReader(StreamReader reader)
    {
        this.reader = reader;
    }

    public UInt64 ReadUInt64()
    {
        UInt64 result = 0;

        while (!reader.EndOfStream)
        {
            int c = reader.Read();
            if (char.IsDigit((char) c))
            {
                result = 10 * result + (UInt64) (c - '0');
            }
            else
            {
                break;
            }
        }

        return result;
    }
}

Here is sample code to use this class:

以下是使用此类的示例代码:

using (StreamReader reader = File.OpenText("numbers.txt"))
{ 
    NumberReader numbers = new NumberReader(reader);

    while (! reader.EndOfStream)
    {
        ulong lastNumber = numbers.ReadUInt64();
    }
}