从文件到列表时,我遇到了一些问题。 文件内容如下:
[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()
绝对没有返回任何内容,并且没有任何内容添加到列表中 - 不应该跳转到下一行并分配给directions
?整件事导致StackOverflowException
。
答案 0 :(得分:1)
在阅读]
字符后,您认为阅读该行已完成,并认为directions = reader.ReadLine();
将以某种方式让您以这种方式
但是,您还没有读完该行,因为]
后面有“换行符”字符,而您的读者读取该字符并返回空字符串。
答案 1 :(得分:1)
我已将您的方法重构为
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等房间名称。
答案 2 :(得分:1)
您所指的具体问题是因为您在某个时间阅读了一个字符,当您看到]
时,您会执行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;
}
我已经包含了一些您可能需要决定如何处理的潜在错误案例。
答案 3 :(得分:0)
如果in in得到满足,那么在读取下一个字符之后,如果条件
则不满足