0

以下代码应该读取文件的每一行并对其进行操作。但是,它只读取第一行。如果没有 for 循环,它会读取整个文件。老实说,我不知道为什么它没有阅读整个内容。

StreamReader sr = new StreamReader(gridPath);

string line;
char[] lineCh;
char current;
int x, y;
bool north, east, south, west;

x = y = 0;

while ((line = sr.ReadLine()) != null)
{
    lineCh = line.ToCharArray();
    for (int i = 0; i < lineCh.Length; i++)
    {
        current = lineCh[i];
        north = CheckInput(current);
        current = lineCh[++i];
        east = CheckInput(current);
        current = lineCh[++i];
        south = CheckInput(current);
        current = lineCh[++i];
        west = CheckInput(current);
        i++; // Hop over space
        grid[x, y] = new GridSquare(north, east, south, west);
        x++; // Start next column
    }
    Console.WriteLine(line);
    y++;
}

如果没有 for 循环,以下工作并打印整个文件:

StreamReader sr = new StreamReader(gridPath);

string line;
char[] lineCh;
char current;
int x, y;
bool north, east, south, west;

x = y = 0;

while ((line = sr.ReadLine()) != null)
{
    lineCh = line.ToCharArray();

    Console.WriteLine(line);
    y++;
}

sr.Close();     

检查输入如下:

private bool CheckInput(char c)
{
    switch (c)
    {
        case 'y':
            return true;
        case 'n':
            return false;
        default:
            return true;
    }
}

示例输入文件:

nyyn nyyy nyyy nyyy nyyy nnyy
yyyn yyyy yyyy yyyy yyyy ynny
yyyn yyyy yyyy yyyy ynyy nnnn
yyyn yyyy yyyy yyyy ynyy nnnn
yyyn yyyy yyyy yyyy yyyy nnyy
yynn yyny yyny yyny yyny ynny
4

7 回答 7

6

您是否在 for 循环中遇到异常?您正在增加 i,也许在某些时候您正试图错误地索引lineCh

编辑:坏索引的另一个候选者是grid数组。我看不到初始化代码, 和 的值xy在读取文件后确定的。你如何初始化它?

于 2010-03-05T11:23:59.453 回答
3

您正在修改循环体内的循环控制变量,这是您应该避免的事情,因为它会导致您的循环意外执行。

请显示您尝试处理的行的示例,我也许可以建议更好地实现您的 for 循环。

您需要一次处理整行还是需要将其分成 4 个字符的块,处理这 4 个字符,然后移动到下一行?

您可以尝试更改处理线路的方式:

        while ((line = sr.ReadLine()) != null)
        {
            string[] segments = line.Split(' ');

            foreach(string segment in segments)
            {
                char[] arr = segment.ToCharArray();
                north = CheckInput(arr[0]);
                east = CheckInput(arr[1]);
                west = CheckInput(arr[2]);
                south = CheckInput(arr[3]);
                grid[x, y] = new GridSquare(north, east, south, west);
            }


            Console.WriteLine(line);
            y++;
        }

在这里,我根据空格分割行,然后我可以通过分割成字符数组并访问特定字符来对单个段进行操作。

这段代码还假设每个段总是有 4 个字符,会一直这样吗?您还应该添加验证以确保该行是您所期望的。

于 2010-03-05T11:28:46.960 回答
1

我觉得你的问题可能是...

for (int i = 0; i < lineCh.Length; i++)

结合许多 ++i 语句。

这是带有大量注释的代码......假设每一行都是“1234”。

        StreamReader sr = new StreamReader(gridPath);

        string line;
        char[] lineCh;
        char current;
        int x, y;
        bool north, east, south, west;

        x = y = 0;

        while ((line = sr.ReadLine()) != null)
        // line is "yyyy"
        {
            lineCh = line.ToCharArray();
            // lineCh.Length is 4
            for (int i = 0; i < lineCh.Length; i++)
            {
                current = lineCh[i]; // i is zero
                north = CheckInput(current);
                current = lineCh[++i]; // i is 1
                east = CheckInput(current);
                current = lineCh[++i]; // i is 2
                south = CheckInput(current);
                current = lineCh[++i];  // i is 3
                west = CheckInput(current);
                i++; // Hop over space // i is 4
                grid[x, y] = new GridSquare(north, east, south, west);
                // (true,true,true,true)
                // So essentially the loop ends if there are four,
                // or goes round again for multiples of 4 - of course,
                // it will error if there is ever 3, or 5 or any other non multiple of 4

                x++; // Start next column
            }
于 2010-03-05T11:22:11.360 回答
1

您的代码会引发异常,因为您可以在任何这些行中获取数组边界:

current = lineCh[++i];
于 2010-03-05T11:25:37.440 回答
1

在循环本身内增加循环变量是危险的。我建议为您的北、东等变量创建一个自定义类型,然后将每一行用到最后。或者甚至更好地返回下一个 GridSquare 对象。

这可以通过返回 GridSquares 的迭代器的方法来完成:

StreamReader sr = new StreamReader("input.txt");

string line;
char[] lineCh;
char current;
int x, y;
bool north, east, south, west;

x = y = 0;

while ((line = sr.ReadLine()) != null)
{
    foreach (var gs in GetGridSquares(line))
    {
        // grid[x, y] = gs;
    }

     Console.WriteLine(line);
     y++;
 }

GetGridSquares 是:

 private IEnumerable<GridSquare> GetGridSquares(string line)
    {
        var splittedLine = line.Split(' ');
        foreach (var gsStr in splittedLine)
        {
            if (gsStr.Length != 4)
            {
                continue;
            }

            yield return new GridSquare(gsStr[0], gsStr[1], gsStr[2], gsStr[3]);
        }
    }
于 2010-03-05T11:31:28.090 回答
1
StreamReader sr = new StreamReader(gridPath);

var line;       
var y = 0;  

while ((line = sr.ReadLine()) != null)
{
    for(var i =0; i<line.length;i+=2)
    {
        grid[i,y]=new GridSquare(GetBits(line[i],i));
        grid[i+1,y]=new GridSquare(GetBits(line[i],i+1));


    }
    ++y;

}

bool [] GetBits(char bBytes, int n)
{
    var returned = new bool[4];
    bBytes = bBytes << ((n%2)*4);
    for(var i =0; i < 4; ++i)
        returned[i]=(bBytes & (1<<i ) > 0;

}
于 2010-03-05T12:32:26.603 回答
1

我在清理代码后发现的实际答案是 x 从未被设置回零。我们永远不会移动到 grid[,] 的下一行。我意识到这很难从我的例子中解决,我在那里道歉。

于 2010-03-05T17:29:08.707 回答