Как прочитать текстовый файл со смесью int и строк, разделенных пробелом, и сохранить каждый в массив - PullRequest
1 голос
/ 19 марта 2012

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

  • 1642 Футболка из чистой шерсти
  • 613 Redботинки на шнурках
  • 3477 Синяя шляпа с пером
  • ...

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

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

}

Или есть лучший способ сделать это?Я читал пост о Patterns и Regex, но не уверен, как его использовать.

Спасибо!

Ответы [ 4 ]

2 голосов
/ 19 марта 2012

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

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));
}
2 голосов
/ 19 марта 2012

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

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

В вашем примере у вас также нет защиты вашего массива, если в вашем файле более 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);
     }
 }

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

0 голосов
/ 19 марта 2012

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

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 голосов
/ 19 марта 2012

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

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