C# StreamReader ReadLine()返回空字符串,列表中未添加任何内容
我在从文件读取到列表时遇到一些问题。 文件内容如下所示:C# StreamReader ReadLine()返回空字符串,列表中未添加任何内容,c#,list,file,streamreader,C#,List,File,Streamreader,我在从文件读取到列表时遇到一些问题。 文件内容如下所示: [ROOM101] that way this way no way all the way [END] [ROOM102] all the way that way this way no way [END] [ROOM103] no way all the way that way this way [END] public static List<Room> ReadRooms(string path) { L
[ROOM101]
that way this way no way all the way
[END]
[ROOM102]
all the way that way this way no way
[END]
[ROOM103]
no way all the way that way this way
[END]
public static List<Room> ReadRooms(string path)
{
List<Room> rooms = new List<Room>();
StreamReader reader = new StreamReader(path);
bool roomsLeft = true;
char currentChar;
string directions;
StringBuilder builder = new StringBuilder();
while (roomsLeft) {
currentChar = (char)reader.Read();
if (currentChar == '[') {
currentChar = (char)reader.Read();
while (currentChar != ']') {
builder.Append(currentChar);
currentChar = (char)reader.Read();
}
if (builder.ToString() != "END") {
directions = reader.ReadLine();
rooms.Add(new Room(builder.ToString(), directions));
}
}
if (reader.EndOfStream) {
roomsLeft = false;
}
}
reader.Close();
return rooms;
}
方法如下所示:
[ROOM101]
that way this way no way all the way
[END]
[ROOM102]
all the way that way this way no way
[END]
[ROOM103]
no way all the way that way this way
[END]
public static List<Room> ReadRooms(string path)
{
List<Room> rooms = new List<Room>();
StreamReader reader = new StreamReader(path);
bool roomsLeft = true;
char currentChar;
string directions;
StringBuilder builder = new StringBuilder();
while (roomsLeft) {
currentChar = (char)reader.Read();
if (currentChar == '[') {
currentChar = (char)reader.Read();
while (currentChar != ']') {
builder.Append(currentChar);
currentChar = (char)reader.Read();
}
if (builder.ToString() != "END") {
directions = reader.ReadLine();
rooms.Add(new Room(builder.ToString(), directions));
}
}
if (reader.EndOfStream) {
roomsLeft = false;
}
}
reader.Close();
return rooms;
}
公共静态列表阅览室(字符串路径)
{
列表房间=新列表();
StreamReader=新的StreamReader(路径);
bool roomsLeft=真;
字符当前字符;
弦方向;
StringBuilder=新的StringBuilder();
while(roomsLeft){
currentChar=(char)reader.Read();
如果(currentChar=='['){
currentChar=(char)reader.Read();
而(currentChar!=']'){
builder.Append(currentChar);
currentChar=(char)reader.Read();
}
if(builder.ToString()!=“END”){
方向=reader.ReadLine();
添加(新房间(builder.ToString(),方向));
}
}
if(reader.EndOfStream){
roomsLeft=假;
}
}
reader.Close();
返回室;
}
它可以很好地读取第一行,但是
directions=ReadLine()
绝对不会返回任何内容,并且不会向列表中添加任何内容-它不应该跳转到下一行并指定给directions
?。如果with in While得到满足,则整个过程会导致一个StackOverflowException
如果读取]
字符后,下一个字符被读取,而第一个字符不满足if条件,则假定读取行已完成,并认为方向=reader.ReadLine()代码>会让你这样做的,不会一直这样
但是,您还没有读完这一行,因为]
后面有一个“换行”字符,您的阅读器确实读取了它并返回了一个空字符串。我已将您的方法重构为
public static List<Room> ReadRooms(string path)
{
List<Room> rooms = new List<Room>();
string roomName=String.Empty;
StringBuilder directionsBuilder= new StringBuilder();
using (StreamReader reader = new StreamReader(path))
{
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
if (line != null && line.StartsWith("[END]"))
{
rooms.Add(new Room(roomName, directionsBuilder.ToString()));
directionsBuilder.Clear();
}
else if (line != null && line.StartsWith("["))
roomName = line.Substring(1, line.Length - 2);
else
directionsBuilder.AppendLine(line);
}
}
return rooms;
}
公共静态列表阅览室(字符串路径)
{
列表房间=新列表();
string roomName=string.Empty;
StringBuilder directionsBuilder=新建StringBuilder();
使用(StreamReader=新StreamReader(路径))
{
而(!reader.EndOfStream)
{
字符串行=reader.ReadLine();
if(line!=null&&line.StartsWith(“[END]”)
{
添加(新房间(roomName,DirectionBuilder.ToString());
directionsBuilder.Clear();
}
else if(line!=null&&line.StartsWith(“[”)
roomName=line.Substring(1,line.Length-2);
其他的
DirectionBuilder.AppendLine(行);
}
}
返回室;
}
它应该处理多行方向以及房间名称,如ROOM102或APARTMENT201等。您所指的具体问题是,您一次读取一个字符,当您看到]
时,您会执行读取行
,但这只会读到]
后面的换行符,而不是你想要的下一行。但是,即使您修复了代码中存在的其他问题(如不清除StringBuilder
),最好只处理行,而不是一次读取一个字符。此外,您可以使用方便的File.ReadLine
方法,而不是使用需要清理的StreamReader
public static List<Room> ReadRooms(string path)
{
List<Room> rooms = new List<Room>();
bool inRoom = false;
StringBuilder directions = new StringBuilder();
string name = null;
foreach (var line in File.ReadLines(path))
{
if (inRoom)
{
if(line == "[END]")
{
rooms.Add(new Room(name, directions.ToString()));
inRoom = false;
directions.Clear();
}
else if (line.StartsWith("[") && line.EndsWith("]"))
{
// Found a start before the end, condiser throwing an
// exception, ignoring, or keep it as part of the directions.
}
else
{
directions.AppendLine(line);
}
}
else
{
if(line == "[END]")
{
// Found an end before a start either throw an exception or
// just ignore this.
}
else if (line.StartsWith("[") && line.EndsWith("]"))
{
inRoom = true;
name = line.Trim('[', ']');
}
else
{
// Consider throwing an exception here or just ignoring lines
// between [END] and the next room.
}
}
}
if (inRoom)
{
// Determine what to do if you had a room start, but no [END]
}
return rooms;
}
公共静态列表阅览室(字符串路径)
{
列表房间=新列表();
bool-inRoom=false;
StringBuilder方向=新建StringBuilder();
字符串名称=null;
foreach(File.ReadLines(路径)中的var行)
{
如果(房间内)
{
如果(第行=“[结束]”)
{
添加(新房间(名称、方向.ToString());
inRoom=假;
方向。清除();
}
else if(line.StartsWith(“[”)&&line.EndsWith(“]))
{
//在结束前找到一个开始,康迪塞扔了一个
//异常、忽略或将其作为指示的一部分保留。
}
其他的
{
方向。追加行(行);
}
}
其他的
{
如果(第行=“[结束]”)
{
//在开始之前找到结束抛出异常或
//忽略这一点。
}
else if(line.StartsWith(“[”)&&line.EndsWith(“]))
{
inRoom=真;
name=line.Trim('[',']');
}
其他的
{
/考虑在此处抛出异常或忽略线
//在[终点]和隔壁房间之间。
}
}
}
如果(房间内)
{
//确定如果您有一个房间开始,但没有[结束]怎么办
}
返回室;
}
我已经列出了一些您需要决定如何处理的潜在错误案例。因为您最后读到的是]
,而不是换行符。为什么不读入这些行,只检查行是否以[
开头,以]
结尾,或者是否为“[END]”,而不是一次读取一个字符?代码会向后看。你怎么知道还有没有读文件的房间?通常,您会在StreamReader上循环,直到达到null(文件末尾)。我建议您将新行读入一个变量,然后在该行上执行您的逻辑,因为流读取器将从您以前的读取继续读入下一个新行图表。谢谢。我已经根据你的答案修改了我的代码,它是有效的,我明白为什么。非常感谢。