2010-03-05 2 views
0

Следующий фрагмент кода должен читать каждую строку файла и работать с ним. Однако он читает только первую строку. Без цикла for он считывает весь файл. Я честно понятия не имею, почему он не читает все это.Почему этот StreamReader читает только одну строку?

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

Без цикл следующих работ и выводит весь файл:

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 
+0

Как боковая точка, вам не нужно превращать строку в массив символов, у String есть указатель на ней, вы можете использовать – thecoop

+0

Возможно, потому что файл содержит одну строку? –

+0

@Mehrdad: tsv говорит: «Без цикла for он считывает весь файл». Поэтому я использую тот же файл. – RvdK

ответ

1

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

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 
      } 
+0

, почему это проблема? ++ i не совпадает с концом массива char. Предположительно, в 1 строке имеется более 1 сетки. – RvdK

+0

Я прокомментировал образец кода, чтобы помочь прояснить ... – Fenton

+0

Ему нужно работать только с моими «официальными» вводами, образец которых я теперь дал – tsvallender

6

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

EDIT: еще один кандидат на плохое индексирование - это массив grid. Я не вижу кода инициализации, а значения x и y определяются после прочтения файла. Как вы его инициализируете?

+0

+1 потому что это единственная возможность, которая имеет смысл. –

+0

Отсутствие исключения из цикла. Он читает одну целую строчку; конечно, он должен перезагрузиться и прочитать остальные тоже? – tsvallender

+0

+1 и, вероятно, урок, извлеченный из того, что исключения – kenny

1

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

current = lineCh[++i]; 
+0

+1. Именно проблема! –

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

+0

Добавили пример ввода. – tsvallender

+1

Хорошее мышление вне коробки. Даже вы можете оставить ToCharArray – RvdK

+0

Спасибо, предоставил мне гораздо более чистый код, который позволил мне понять реальную ошибку! – tsvallender

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

} 
Смежные вопросы