2012-04-15 6 views
1

Этот код генерирует исключение: «Индекс находился за пределами массива». Разве это не должно просто добавить каждый из разделенных данных в выделенный слот массива?Проблемы с методом .Split()

while (input != null) 
{ 
    string[] splitInput = inputLine.Split(); 
    EmpNum = int.Parse(splitInput[0]); 
    EmpName = (splitInput[1]); 
    EmpAdd = (splitInput[2]); 
    EmpWage = double.Parse(splitInput[3]); 
    EmpHours = double.Parse(splitInput[4]); 
    inputLine = (myFile.ReadLine()); 
    Console.WriteLine("test {0},{1},{2}", EmpNum, EmpWage, EmpHours); 
} 

Чтобы прояснить немного, я чтение данных из простого текстового файла, содержащего данные о сотрудниках (имя, адрес, часы, номер сотрудника, заработная плата).

Я добавил весь свой основной метод для ясности.

using System; 
using System.IO; 

class Program 
{ 
static void Main() 
{ 

    //declare an array of employees 
    Employee[] myEmployees = new Employee[10]; 

    //declare other variables 
    string inputLine; 
    string EmpName; 
    int EmpNum; 
    double EmpWage; 
    double EmpHours; 
    string EmpAdd; 

    //declare filepath 
    string environment =   System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal) + "\\"; 

    //get input 
    Console.Write("\nEnter a file name in My Documents: "); 
    string input = Console.ReadLine(); 
    string path = environment + input; 
    Console.WriteLine("Opening the file..."); 

    //read file 
    StreamReader myFile = new StreamReader(path); 
    inputLine = (myFile.ReadLine()); 

    //split input 
    while (inputLine != null) 
    { 

     string[] splitInput = inputLine.Split(); 
     EmpNum = int.Parse(splitInput[0]); 
     EmpName = (splitInput[1]); 
     EmpAdd = (splitInput[2]); 
     EmpWage = double.Parse(splitInput[3]); 
     EmpHours = double.Parse(splitInput[4]); 
     Console.WriteLine("test {0},{1},{2}", EmpNum, EmpWage, EmpHours); 
    } 

    Console.ReadLine(); 
}//End Main() 
}//End class Program 
+0

Кроме того, если требуется любая другая информация, я могу разместить больше моего кода. – xavi

+0

, когда вы разделите свой 'inputLine', вы получите меньше 5 элементов. – bjarneh

+0

Не следует' while (input! = Null) 'вместо be' while (inputLine! = Null) '? –

ответ

1

Может быть, эта версия будет хорошо для дополнительного кредита :) Серьезно, хотя я не пытаюсь показать здесь - это просто, что несмотря на то, что это пример обучения, если вы получите работу, и дается задание для написания кода, который читает CSV-файл, например, вы не хотите, чтобы он разбился и заставил вас выглядеть плохо, поэтому вы окажете себе одолжение, чтобы узнать о некоторых шагах, чтобы сделать его более надежным.

Примечание. Это не попытка начать дискуссию по идеальному способу кодирования вашего примера - просто попытка показать несколько трюков, которые, как я знаю, являются полезными. Надеюсь, это поможет.

  StreamReader myFile = new StreamReader("TextFile1.txt"); 
      int lineNumber = 0; 
      while (!myFile.EndOfStream) 
      { 
       // Read the next line. 
       string inputLine = myFile.ReadLine(); 
       lineNumber++; 

       // Extract fields line. 
       string[] splitInput = inputLine.Split(); 

       // Make sure the line has the correct number of fields. 
       if (splitInput.Length == 5) 
       { 
        // Parse and validate each field. 

        if (!int.TryParse(splitInput[0], out EmpNum)) 
        { 
         Console.WriteLine("could not parse int " + splitInput[0] + " on line " + lineNumber); 
         continue; 
        } 

        EmpName = (splitInput[1]); 

        EmpAdd = (splitInput[2]); 

        if(!double.TryParse(splitInput[3], out EmpWage)) 
        { 
         Console.WriteLine("could not parse double " + " on line " + lineNumber); 
         continue; 
        } 

        EmpHours = double.Parse(splitInput[4]); 

        if (!double.TryParse(splitInput[4], out EmpHours)) 
        { 
         Console.WriteLine("could not parse double: " + " on line " + lineNumber); 
         continue; 
        } 

        // Output 
        Console.WriteLine("test {0},{1},{2}", EmpNum, EmpWage, EmpHours); 
       } 
       else 
       { 
        Console.WriteLine("Expecting 5 items from split opertation but got " + splitInput.Length + " on line " + lineNumber); 
       } 
      } 
      myFile.Close(); 

TextFile1.txt

1 2 3 4 5 
6 7 8 f9 10 
11 12 

Программа выходного

test 1,5,5 
could not parse double: on line 2 
Expecting 5 items from split opertation but got 2 on line 3 
+0

спасибо! это прекрасно – xavi

+0

рад помочь ... –

1

Проверьте строку, которую вы не можете получать 5 элементов ввода и обеспечивают некоторый характер в методе расщепления

Изменения inputLine.Split() к inputLine.Split(','), если вы отделяете элемент запятой

вашего вклада будет как «первый», «второй», «третий», «четвертый», «пятый»

+0

Я начинаю осознавать свою ошибку. ОК. Поэтому я создал класс под названием «Сотрудник», и я создал массив из 10 этих объектов-сотрудников. Мне действительно нужно прочитать данные из этого файла и сохранить ссылки в этом массиве объектов-сотрудников. Надеюсь, это прояснит ситуацию. – xavi

+0

повторите этот шаблон в файле и сделайте 5 строк «первый», «второй», «третий», «четвертый», «пятый», затем прочитайте файл для ввода, вы можете найти, как читать из файла здесь http://msdn.microsoft .com/en-us/library/ms228592 (v = vs.80) .aspx – Adil

0

1) Должно ли input быть inputLine?

2) Добавьте нулевой флажок для каждого элемента массива перед его использованием.

Также я предполагаю,

while (input != null) 
    { 
     string[] splitInput = inputLine.Split(); 
     EmpNum = int.Parse(splitInput[0]); 
     EmpName = (splitInput[1]); 
     EmpAdd = (splitInput[2]); 
     EmpWage = double.Parse(splitInput[3]); 
     EmpHours = double.Parse(splitInput[4]); 
     inputLine = (myFile.ReadLine()); 
     Console.WriteLine("test {0},{1},{2}", EmpNum, EmpWage, EmpHours); 
    } 

должен быть

while (input != null) 
    { 
     inputLine = (myFile.ReadLine()); 
     string[] splitInput = inputLine.Split(); 
     EmpNum = int.Parse(splitInput[0]); 
     EmpName = (splitInput[1]); 
     EmpAdd = (splitInput[2]); 
     EmpWage = double.Parse(splitInput[3]); 
     EmpHours = double.Parse(splitInput[4]); 

     Console.WriteLine("test {0},{1},{2}", EmpNum, EmpWage, EmpHours); 

}

Первое чтение из файла с помощью inputLine = (myFile.ReadLine());, а затем выполнить операцию разделения ...

3) Как было предложено Аароном Анодидом, addin проверка га для длины должны сделать трюк ..

что-то вроде ..

inputLine = (myFile.ReadLine()); 
string[] splitInput = inputLine.Split(); 
if(splitInput!=null && splitInput.length ==5) 
{ 
EmpNum = int.Parse(splitInput[0]); 
     EmpName = (splitInput[1]); 
     EmpAdd = (splitInput[2]); 
     EmpWage = double.Parse(splitInput[3]); 
     EmpHours = double.Parse(splitInput[4]); 
     Console.WriteLine("test {0},{1},{2}", EmpNum, EmpWage, EmpHours); 
} 
+1

как вы относитесь к добавлению к вашему ответу проверки длины массива после операции split? Я думаю, что это было бы полезно для плаката ... –

+0

Проверка нулевых значений в массиве вообще не помогает. В массиве никогда не будет никаких нулевых значений. – Guffa

+0

@ Guffa: Вы имеете в виду элементы массива или массива ?. Если вы ссылаетесь на 'splitInput! = Null', я добавил его только для того, чтобы быть на более безопасной стороне перед использованием свойства. Если вы ссылаетесь на элементы массива, скажите, если строка в файле содержит только 3 элемента, не будут ли остальные элементы пустыми? –

0

Добавить точку останова на линию после того, как вы разделяете вход, то вы можете мыши над результирующим массивом и нажмите на знак плюс , Таким образом вы можете точно определить, как данные разбиваются. Это особенно полезно, если есть скрытые символы, которые отбрасывают раскол (\ n, \ t, \ r).

1

У вас есть строка, которая не содержит достаточно предметов. Проверьте длину массива перед чтением пунктов:

string[] splitInput = inputLine.Split(); 
if (splitInput.Length >= 5) { 
    EmpNum = int.Parse(splitInput[0]); 
    EmpName = (splitInput[1]); 
    EmpAdd = (splitInput[2]); 
    EmpWage = double.Parse(splitInput[3]); 
    EmpHours = double.Parse(splitInput[4]); 
} else { 
    // not enough items - show an error message or something 
} 

Кроме того, вы проверяете переменную input вместо inputLine в where, но это не является причиной ошибки, которые вы получаете. Если вы прочитали до конца файла, вы получите исключение с ссылкой на null при попытке использовать нулевую ссылку в split.

0

У вас есть несколько проблем. Первая проблема заключается в том, что Split(). Вам необходимо изменить inputLine.Split() на inputLine.Split(','). Прямо сейчас вы вызываете перегрузку System.String.Split(params char[]), и поскольку вы не указываете какие-либо символы для разделения, он возвращает всю строку.

Другие проблемы (как студент CS), вы должны действительно работать над вашими соглашениями об именах и проверкой ошибок. Код довольно хрупкий и очень легко ломается. Вы должны начать на ранней стадии обучения хорошей практике разработки программного обеспечения и написания высококачественного кода.

using (FileStream fstream = new FileStream("path", FileMode.Open)) 
using (StreamReader reader = new StreamReader(fstream)) { 
    string line; 

    while (!reader.EndOfStream && (line = reader.ReadLine()) != null) { 
     string[] data = line.Split(','); 

     if (data.Length < 5) { 
      // You will have IndexOutOfRange issues 
      continue; // skip processing the current loop 
     } 

     int employeeNumber; 
     string employeeName; 
     string employeeAddress; 
     double employeeWage; 
     double employeeHours; 

     // Will be used to check validity of fields that require parsing into a type. 
     bool valid; 

     valid = int.TryParse(data[0], out employeeNumber); 

     if (!valid) { 
      // employee number is not parsable 
     } 

     employeeName = data[1]; 
     employeeAddress = data[2]; 

     valid = double.TryParse(data[3], out employeeWage); 

     if (!valid) { 
      // employee wage is not parsable 
     } 

     valid = double.TryParse(data[4], out employeeHours); 

     if (!valid) { 
      // employee hours are not parsable 
     } 
    } 
} 
+0

Спасибо за предложения! – xavi

+0

также, не могли бы вы объяснить действительный bool? Я ценю ваш ответ! – xavi

+0

Это проверка неверных данных. 'double.Parse' генерирует исключение, если ваши данные неверны.Предположим, что ваш файл данных случайно содержит символ '-' (общий после ввода 0). 'double.Parse' будет терпеть неудачу и выбросить исключение. Решение заключается в использовании 'double.TryParse', который возвращает true, если вход был преобразован в double успешно, иначе возвращает false, если произошла ошибка (ваши данные были искажены). Это предотвращает исключение исключения и позволяет корректно обрабатывать проблему в коде. –

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