Почему этот StreamReader читает только одну строку? - PullRequest
0 голосов
/ 05 марта 2010

Следующий фрагмент кода должен прочитать каждую строку файла и работать с ней. Тем не менее, он читает только первую строку. Без цикла 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();     

CheckInput выглядит следующим образом:

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

Ответы [ 7 ]

6 голосов
/ 05 марта 2010

Получаете ли вы исключение в цикле for?Вы увеличиваете i, возможно, в какой-то момент вы пытаетесь неправильно индексировать lineCh.

РЕДАКТИРОВАТЬ : еще одним кандидатом для плохой индексации является массив grid.Я не вижу кода инициализации, и значения x и y определяются после чтения файла.Как вы его инициализируете?

3 голосов
/ 05 марта 2010

Вы изменяете переменную управления циклом внутри тела вашего цикла, этого вам следует избегать, так как это приведет к неожиданному выполнению вашего цикла.

Пожалуйста, покажите пример строки, которую вы пытаетесьдля обработки, и я, возможно, смогу предложить лучшую реализацию вашего цикла 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 символа, будет ли это всегда так?Вы также должны добавить проверку, чтобы убедиться, что строка соответствует ожидаемой.

1 голос
/ 05 марта 2010

Фактический ответ, который я нашел после очистки кода, состоял в том, что x никогда не обнуляется; мы никогда не переходим к следующему ряду сетки [,]. Я понимаю, что это было трудно понять из моих примеров, извинений.

1 голос
/ 05 марта 2010
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;

}
1 голос
/ 05 марта 2010

Опасно увеличивать циклическую переменную внутри самого цикла. Я бы порекомендовал создать собственный тип для ваших северных, восточных и т. Д. Переменных, а затем использовать каждую строку до конца. Или, может быть, лучше вернуть следующий объект 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]);
        }
    }
1 голос
/ 05 марта 2010

ваш код вызывает исключение, потому что вы можете получить границы массива в любой из этих строк:

current = lineCh[++i];
1 голос
/ 05 марта 2010

Я думаю, что ваша проблема может быть ...

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
            }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...