[英]C# reading a string from text file, splitting and putting into tabstring
I got stuck writing some simple program which writes some data to the text file and reads them form this file later.我在编写一些简单的程序时遇到了困难,该程序将一些数据写入文本文件并稍后从该文件中读取它们。
I have a function that writes lines to a txt file;我有一个 function 将行写入 txt 文件; each line contains Name, Surname, and Idnumber.
每行包含姓名、姓氏和身份证号码。
And below I have a function that reads the data from that file.下面我有一个 function 从该文件中读取数据。
I want to separate Name, Surname and Idnumber so below code seems to be correct but during debugging I got a message "An unhandled exception of type 'System.NullReferenceException' occurred" for this line: string[] tabstring = myString.Split(' ', ' ');
我想将姓名、姓氏和身份证号码分开,所以下面的代码似乎是正确的,但在调试过程中,我收到一条消息“发生了此行的未处理的 'System.NullReferenceException' 类型的异常”:
string[] tabstring = myString.Split(' ', ' ');
. .
I created the tab string which contains 3 elements - each for each word in the line ie tabstring[0]=Name and so on.我创建了包含 3 个元素的选项卡字符串 - 每个元素对应于行中的每个单词,即 tabstring[0]=Name 等等。
The while
loop is to do it for each line in the text file. while
循环是对文本文件中的每一行执行此操作。 But something is wrong.但有些不对劲。
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();
}
And here is what the text file looks like:这是文本文件的样子:
Ann Brown 1233456789
Bruce Willis 098987875
Bill Gates 789678678
and so on...等等...
I would appreciate your comments on the described problem.感谢您对所描述问题的评论。
Your problem is here:你的问题在这里:
while (srListOfObjects.ReadLine() != null)
{
string myString= (srListOfObjects.ReadLine();
You are entering the loop on the condition that srListOfObjects.ReadLine()
returns something other than null
but then you are immediately reading a new line form srListOfObjects
and storing the returned reference in myString
.您正在进入循环,条件是
srListOfObjects.ReadLine()
返回null
以外的内容,但随后您将立即读取新的行形式srListOfObjects
并将返回的引用存储在myString
中。 This has obviously two problems:这显然有两个问题:
ReadLine
can return null
and you are not checking if it is.ReadLine
可以返回null
并且您没有检查它是否是。 The error you are getting is due to this reason. Update: You should only read one line per iteration.更新:每次迭代您应该只阅读一行。 One way to do it is declaring and initializing
myString
before entering the loop and updating it on every iteration:一种方法是在进入循环之前声明和初始化
myString
并在每次迭代时更新它:
var myString = srListOfObjects.ReadLine();
while (myString != null)
{
//do your stuff
myString = srListOfObjects.ReadLine();
}
https://docs.microsoft.com/en-us/dotnet/api/system.io.streamreader.readline?view=netcore-3.1 https://docs.microsoft.com/en-us/dotnet/api/system.io.streamreader.readline?view=netcore-3.1
ReadLine() - Reads a line of characters from the current stream and returns the data as a string. ReadLine() - 从当前 stream 中读取一行字符并将数据作为字符串返回。
In your code you do a null check, but then call ReadLine again.在您的代码中,您执行 null 检查,然后再次调用 ReadLine。 When you hit the last line, you will get a NULL string, and splitting that will fail with the NULL ref
当您点击最后一行时,您将得到一个 NULL 字符串,并且拆分将失败并使用 NULL 参考
while (srListOfObjects.ReadLine()..
reads a line but doesn't save it into a variable. string myString= (srListOfObjects.ReadLine())
reads another line. while (srListOfObjects.ReadLine()..
读取一行但不将其保存到变量中。 string myString= (srListOfObjects.ReadLine())
读取另一行。
Use while (.srListOfObjects.EndOfStream)
to check for the end of the stream: StreamReader.EndOfStream Property .使用
while (.srListOfObjects.EndOfStream)
检查 stream: StreamReader.EndOfStream 属性的结尾。
Also, it is a good idea to check that the correct number of parts of the string were obtained by the Split - it guards against things like lines with only whitespace.此外,检查拆分是否获得了正确数量的字符串部分是一个好主意 - 它可以防止诸如只有空格的行之类的事情。
Things like StreamReaders need have.Dispose() called on them to clear up "unmanaged resources" - an easy way to do that which will work even if the program crashes is to use the using
statement. StreamReaders 之类的东西需要 have.Dispose() 调用它们以清除“非托管资源” - 一种简单的方法,即使程序崩溃也可以使用
using
语句。
If you make the ReadFromFile
method into a function instead of a void then you can avoid (no pun) using a global variable for the data.如果您将
ReadFromFile
方法变成 function 而不是 void,那么您可以避免(无双关语)对数据使用全局变量。 Global variables are not necessarily a problem, but it's usually good to avoid them.全局变量不一定是问题,但通常最好避免它们。
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();
}
}
}
outputs:输出:
1233456789 - Brown, Ann
1233456789 - 布朗,安
98987875 - Willis, Bruce98987875 - 威利斯,布鲁斯
789678678 - Gates, Bill789678678 - 盖茨,比尔
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.