StreamReader ReadLine() returns 空字符串,没有添加到列表

StreamReader ReadLine() returns empty string, nothing added to list

我在从文件读取到列表时遇到一些问题。 文件内容是这样的:

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

它读取第一行没问题,但是 directions = ReadLine() returns 绝对没有,也没有任何内容添加到列表中 - 它不应该跳到下一行并分配给 directions?.整个结果是 WhosebugException.

if with in While 得到满足然后读取下一个不满足第一个 if 条件的字符

阅读完 ] 字符后,您认为该行已完成阅读并认为 directions = reader.ReadLine(); 会让您 that way this way no way all the way

但是,您还没有读完该行,因为在 ] 之后有 "newline" 字符,而您的 reader 确实读取了该行,并且 returns 是一个空字符串.

我已经将你的方法重构为

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

它应该处理多行方向以及房间名称,如 ROOM102 或 APARTMENT201 等

您提到的具体问题是因为您一次读取一个字符,当您看到 ] 时,您会执行 ReadLine,但这只会读取到换行符在 ] 之后,而不是您想要的下一行。但是,即使您修复了代码中存在的其他问题(例如未清除 StringBuilder),最好只处理行而不是一次读取一个字符。此外,除了使用需要清理的 StreamReader 之外,您还可以使用方便的 File.ReadLine 方法。

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

我列出了一些潜在的错误案例,您需要决定如何处理。