C#从文本文件读取字符串,拆分并放入TabString

时间:2020-05-05 10:30:55

标签: c# string list file split

我被困在编写一些简单的程序,该程序将一些数据写入文本文件,然后再从该文件读取它们。

我有一个将行写入txt文件的功能;每行包含名称,姓氏和ID号。

下面,我有一个函数可以从该文件中读取数据。

我想分隔名称,姓氏和ID号,因此下面的代码似乎是正确的,但是在调试过程中,此行收到消息“发生了'System.NullReferenceException'类型的未处理异常”: ErrorException: Undefined variable: request in /var/www/html/sd/app/Jobs/EunoS.php:43

我创建了一个制表符字符串,其中包含3个元素-行中每个单词的每个元素,即tabstring [0] = Name等。

string[] tabstring = myString.Split(' ', ' ');循环是针对文本文件中的每一行执行的操作。但是出了点问题。

while

这是文本文件的外观:

public void ReadFromFile()
        {
           FileStream fsListOfObjects = new FileStream("C:\\Users\\Dom\\Desktop\\ListOfObjects.txt", 
           FileMode.Open);
            StreamReader srListOfObjects = new StreamReader(fsListOfObjects);

            while (srListOfObjects.ReadLine() != null)
            {
                string myString= (srListOfObjects.ReadLine();
                Console.WriteLine(myString);
                **string[] tabstring = myString.Split(' ', ' ');**

                Name = tabstring[0];
                Surname = tabstring[1];
                Id= long.Parse(tabstring[2]);
                ClassName object= new ClassName(Name, Surname, Id);
                myList.Add(object);
            }
            srListOfObjects.Close();

            Console.ReadLine();
        }

以此类推...

感谢您对上述问题的评论。

3 个答案:

答案 0 :(得分:0)

您的问题在这里:

while (srListOfObjects.ReadLine() != null)
{
    string myString= (srListOfObjects.ReadLine();

您进入循环的条件是srListOfObjects.ReadLine()返回null以外的内容,但是随后您立即读取新的行格式srListOfObjects并将返回的引用存储在{{1 }}。这显然有两个问题:

  1. 第二次致电myString可以返回ReadLine,您无需检查是否存在。您收到的错误是由于这个原因。
  2. 您正在丢失信息。在检查while条件时,您将忽略正在读取的行。在程序崩溃或运行到最后(取决于输入文件的行数是偶数还是奇数)之前,您将只处理一半的数据。

更新: 您每次迭代只应阅读一行。一种实现方法是在进入循环之前声明和初始化null并在每次迭代中对其进行更新:

myString

答案 1 :(得分:0)

https://docs.microsoft.com/en-us/dotnet/api/system.io.streamreader.readline?view=netcore-3.1

ReadLine()-从当前流中读取一行字符,并将数据作为字符串返回。

在您的代码中执行空检查,但随后再次调用ReadLine。当您到达最后一行时,将得到一个NULL字符串,并且拆分将失败,并带有NULL ref

答案 2 :(得分:0)

while (srListOfObjects.ReadLine()..读取一行,但不将其保存到变量中。 string myString= (srListOfObjects.ReadLine())读取另一行行。

使用while (!srListOfObjects.EndOfStream)检查流的结尾:StreamReader.EndOfStream Property

此外,最好检查Split是否获得了正确的字符串部分数量-它可以防止只有空格的行之类的东西。

类似StreamReaders的东西需要调用.Dispose()来清除“非托管资源”-一种即使在程序崩溃时也可以使用的简单方法是使用using语句。

如果将ReadFromFile方法变成一个函数而不是一个void,那么可以避免(禁止使用)数据的全局变量。全局变量不一定是问题,但通常最好避免使用它们。

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

namespace ConsoleApp1
{

    public class ClassName
    {
        public string Name { get; set; }
        public string Surname { get; set; }
        public long Id { get; set; }

    }

    class Program
    {
        public static List<ClassName> ReadFromFile(string fileName)
        {
            var result = new List<ClassName>();

            using (var sr = new StreamReader(fileName))
            {
                while (!sr.EndOfStream)
                {
                    string line = sr.ReadLine();
                    var parts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    if (parts.Count() == 3)
                    {
                        result.Add(new ClassName
                        {
                            Name = parts[0],
                            Surname = parts[1],
                            Id = long.Parse(parts[2])
                        });
                    }
                }
            }

            return result;

        }

        static void Main(string[] args)
        {
            string myFile = @"C:\temp\namesList.txt";
            var theList = ReadFromFile(myFile);

            foreach(var c in theList)
            {
                Console.WriteLine($"{c.Id} - {c.Surname}, {c.Name}");
            }

            Console.ReadLine();

        }
    }
}

输出:

1233456789-布朗,安
98987875-威利斯,布鲁斯
789678678-盖茨,比尔