简体   繁体   English

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

[英]Read numbers from a text file in C#

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#? 您如何在C#中做到这一点? For example, in C++, the following code would work to read an integer, float, and word. 例如,在C ++中,以下代码可以读取整数,浮点数和单词。 I don't want to have to use a regex or write any special parsing code. 我不想使用正则表达式或编写任何特殊的解析代码。

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文件也是一个很好的示例,说明了为什么要在读入完整令牌后立即停止读取文件。

Brannon's answer explains how to read binary data. 布兰农的答案解释了如何读取二进制数据。 If you want to read text data, you should be reading strings and then parsing them - for which there are built-in methods, of course. 如果要读取文本数据,则应先读取字符串,然后解析它们-当然,这些字符串具有内置方法。

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 null in z if the file only has two lines. 如果文件只有两行,它将在z保留null值。

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.TryParse and double.TryParse instead of the Parse methods. 对于更健壮的解决方案(可能会更自然地失败),您将需要检查reader.ReadLine()是否返回null (指示文件的末尾),并使用int.TryParsedouble.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.ReadAllText instead, to make it slightly simpler. 请注意,如果文件实际上仅由一行组成,则可能需要使用File.ReadAllText来使其更简单。 There's also File.ReadAllLines which reads the whole file into a string array of lines. 还有File.ReadAllLines ,它将整个文件读入一个字符串行数组。

EDIT: If you need to split by any whitespace, then you'd probably be best off reading the whole file with File.ReadAllText and then using a regular expression to split it. 编辑:如果您需要按任何空格进行拆分,则最好使用File.ReadAllText读取整个文件,然后使用正则表达式进行拆分。 At that point I do wonder how you represent a string containing a space. 在这一点上,我确实想知道您如何表示一个包含空格的字符串。

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. 如果您在二进制文件中需要文本部分,通常最好包括一个长度前缀,以便仅对那段数据进行解码。

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

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

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. XML序列化提供了一种写入和读取XML格式文件的简单方法。 For example, if you have a configuration class like this: 例如,如果您有这样的配置类:

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 XmlSerializer class: 您可以简单地保存它并使用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);
   }
}

Save method 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 Save and Load methods if your Configuration class changes. 这种方法的好处是,如果Configuration类发生更改,则无需更改SaveLoad方法。

I like using the StreamReader for quick and easy file access. 我喜欢使用StreamReader来快速方便地访问文件。 Something like.... 就像是....

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

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 ac# tutorial it will be really useful to have the whole picture in mind before asking 恕我直言,也许要阅读ac#教程,在询问之前记住整个图片将非常有用

C# doesn't seem to have formatted stream readers like C++ (I would be happy to be corrected). C#似乎没有像C ++一样格式化的流读取器(我很乐意得到纠正)。 So Jon Skeet approach of reading the contents as string and parsing them to the desired type would be the best. 因此,Jon Skeet最好将内容读取为字符串并将其解析为所需的类型。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM