2012-03-19 4 views
1

У меня есть текстовый файл с примерно 200 номерами элементов и описаниями, которые отформатированы следующим образом (без патронов):Как читать текстовый файл с сочетанием int и строк, разделенных пробелом, и хранить их в массивах

  • 1642 Чистая шерсть футболки
  • 613 красный кружевной обувь
  • 3477 Синий шлем с пером
  • ...

Я пытаюсь читать d сохраняйте номера и описания элементов в соответствующих массивах, которые ограничены пробелом. Мои вопросы:

  1. Я хочу игнорировать пробелы в описании.
  2. Когда я сортирую или удаляю элементы, я хочу, чтобы описание также удалялось.

Вот что я пытался до сих пор, но получаю ошибку ArrayIndexOutOfBoundsException и я даже не уверен, что если он будет читать описание правильно:

private Scanner file; 
private int item = 0; 
private String desc = ""; 
private int[] itemArr = new int[200]; 
private String[] descArr = new String[200]; 
int n = 0; 


public void openFile(){ 

    try{ 
     file = new Scanner(new File("inventory.txt")); 
    } 

    catch(Exception e){ 
     System.out.println("file not found"); 
    } 

} 

public void readFile(){   

    while(file.hasNextLine()){  
     if (file.hasNextInt()){  
      item = file.nextInt(); 
     } 

     while(!file.hasNextInt() && !file.hasNextLine()){ 
      desc = desc + file.next() + " "; 
     } 

     itemArr[n] = item; 
     descArr[n] = desc; 
     n++; 
    } 

    for (int i = 0; i < n; i++){ 
     System.out.println(itemArr[i] + " " + descArr[n] + "\n"); 
    } 
    System.out.println("Total Records (n): " + n); 

} 

Или есть лучший способ сделать это? Я прочитал несколько сообщений о шаблонах и регулярном выражении, но не знаю, как их использовать.

Спасибо!

+0

Мой совет должен был бы реорганизовать формат входного файла в нечто более представительным, как [JSON] (HTTP: // эн. wikipedia.org/wiki/JSON) или [XML] (http://en.wikipedia.org/wiki/XML), если вы считаете, что использование базы данных не подходит для проблемы, которую вы пытаетесь решить. Фиксированное индексирование массивов отлично подходит для небольшого тестового примера, но оно недостаточно устойчиво, чтобы элегантно обрабатывать изменения в ваших структурах входных данных. В качестве бонуса JSON будет обрабатывать идентификацию типа и [десериализацию] (http://en.wikipedia.org/wiki/Serialization) для вас. – MrGomez

+0

"около 200 наименований"? Если вы точно не знаете длину, я бы рекомендовал использовать Список. Кроме того, я бы рекомендовал создать объект Item для хранения данных, создав хранилище списка . Regex - это способ вытащить отдельные фигуры, но мне это не здорово, поэтому я не могу дать вам образец. – ggrigery

+0

Вам нужно обрабатывать такие предметы, как «1234 Official 39ers Jersey»? – Thomas

ответ

2

Нет защиты на n, превышающем 200. Если есть более 200 итераций цикла while затем:

itemArr[n] = item; 

выбросит ArrayIndexOutOfBoundsException.

Если int в начале каждой строки уникален, вы можете использовать Map<Integer, String> для хранения данных. Это не приведет к ограничению 200 по количеству элементов, которые можно прочитать из файла, и если вы выбрали TreeMap в качестве реализации, он будет сортировать их (вы можете либо принять естественный порядок Integer, либо определить свой собственный Comparator). Как предложено sethu, вы можете использовать BufferedReader для чтения файла.

Например:

BufferedReader br = new BufferedReader(new FileReader("inventory.txt")); 
Map<Integer, String> items = new TreeMap<Integer, String>(); 

String line; 
while (null != (line = br.readLine())) 
{ 
    String[] line_parts = line.split(" "); 
    if (line_parts.length > 1) 
    { 
     StringBuilder desc = new StringBuilder(line_parts[1]); 
     for (int i = 2; i < line_parts.length; i++) 
     { 
      desc.append(line_parts[i]); 
     } 
     items.put(new Integer(line_parts[0]), desc.toString()); 
    } 
} 

for (Integer key: items.keySet()) 
{ 
    System.out.println(key + " = " + items.get(key)); 
} 
+0

Большое вам спасибо, он отлично работает! – OverAir

2

Я бы лично сделал IndexOf для первого пространства, а затем подстроку от 0 до результата IndexOf и ParseInt, чтобы получить номер элемента.

Тогда я бы выполнил подстроку IndexOf до конца строки и выполнил Trim для результата для хорошей меры.

В вашем примере у вас также нет защиты на вашем массиве, если у вас более 200 строк в вашем файле, в вашем массиве вы получите пробел. Вы должны использовать коллекцию как ArrayList

Это будет выглядеть примерно так:

Сначала измените объявление вашего массива для ArrayList

private ArrayList<Integer> itemArr = new ArrayList<Integer>(); 
private ArrayList<String> descArr = new ArrayList<String>(); 

Во-вторых, мы меняем свой алгоритм использовать SubStrings и IndexOf и использовать ArrayList

public void readFile(){   

while(file.hasNextLine()){ 

    String line = file.getNextLine(); 
    int indexOfSpace = line.IndexOf(" "); 
    int item = Integer.parseInt(line.substring(0,indexOfSpace)); 
    String description = line.substring(indexOfSpace).trim(); 

    itemArr.add(item); 
    descArr.add(description); 
    } 
} 

Если вы хотите пойти один шаг фу rther, вы можете создать Class, чтобы представлять свои товары, и вам нужно использовать только один ArrayList вместо 2, но я думаю, что я уже рассмотрел ваш вопрос!

+0

спасибо, но я получаю «синтаксические ошибки в токене» в объявлениях ArrayList: S – OverAir

+0

Я исправил это, мое плохое: D – Alexandre

+0

большое вам спасибо! – OverAir

0

Я не буду писать код, но я дам вам алгоритм:

  1. Используйте BufferedReader, чтобы прочитать каждую строку файла.
  2. Разделите каждую строку на массив строк, основанный на пространстве, используя String.split ("")
  3. Пройдите через каждый элемент массива String и его в StringBuffer, пока не получите строку, в которой все числа. Существует много способов проверки, является ли строка всеми числами. Проверьте каждый символ, используйте регулярное выражение и сопоставьте шаблон, используйте класс Apache commons StringUtils.
  4. Если вы достигли номера, то вы знаете, что все, что вы собрали в StringBuffer, - это описание. Идеальной структурой данных для использования в этом случае является TreeMap. Добавьте описание как ключ и значение в качестве цены. Вы можете сортировать карту и удалять записи, как вам угодно.
+0

Благодарю вас за ваше время – OverAir

0

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

Pattern itemPatt = Pattern.compile("([0-9]+)\\s([a-zA-z\\s]*)"); 

Matcher m = itemPatt.matcher(fileStr); 

if (m.matches()) { 

    int itemNumber = Integer.parseInt(m.group(1)); 

    String itemDescription = m.group(2); 

} 
+0

благодарю вас за ваше время. – OverAir