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(文件末尾)。我建议您将新行读入一个变量,然后在该行上执行您的逻辑,因为流读取器将从您以前的读取继续读入下一个新行图表。谢谢。我已经根据你的答案修改了我的代码,它是有效的,我明白为什么。非常感谢。