Java 如何读取由空格分隔的 int 和字符串混合的文本文件并将每个文件存储到数组中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9772657/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 07:30:30  来源:igfitidea点击:

How to read a text file with a mix of int and strings delimited by space and store each into arrays

javaregexarraysinputjava.util.scanner

提问by OverAir

I have a text file with about 200 item numbers and descriptions, which is formatted like this (without the bullets):

我有一个包含大约 200 个项目编号和描述的文本文件,其格式如下(没有项目符号):

  • 1642 Pure wool t-shirt
  • 613 Red laced shoes
  • 3477 Blue hat with feather
  • ...
  • 1642纯羊毛T恤
  • 613红色系带鞋
  • 3477蓝色带羽毛帽子
  • ...

I am trying to read and store the items numbers and descriptions into respective arrays, which is delimited by space. My issues are:

我正在尝试读取项目编号和描述并将其存储到由空格分隔的各个数组中。我的问题是:

  1. I want to ignore the spaces in the description.
  2. When I sort or delete items, I want to ensure that the description gets deleted as well.
  1. 我想忽略描述中的空格。
  2. 当我排序或删除项目时,我想确保描述也被删除。

Here's what I have tried so far but getting ArrayIndexOutOfBoundsException error and I am not even sure if it will read the description properly:

这是我到目前为止所尝试的,但出现 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);

}

Or is there a better way to do this? I've read some post about Patterns and Regex, but not sure how to use that either.

或者有没有更好的方法来做到这一点?我读过一些关于 Patterns 和 Regex 的文章,但也不知道如何使用它。

Thank you!

谢谢!

采纳答案by hmjd

There is no protection on nexceeding 200. If there are more that 200 iterations of the whileloop then:

没有n超过的保护200。如果while循环的迭代次数超过 200 次,则:

itemArr[n] = item;

will throw an ArrayIndexOutOfBoundsException.

会抛出一个ArrayIndexOutOfBoundsException.

If the intat the beginning of each line is unique you could use a Map<Integer, String>to store the data. This will not place a limit of 200on the number of items that can be read from the file and if you selected a TreeMapas the implementation it would sort them (you can either accept the natural ordering of Integeror define you own Comparator). As suggested by sethuyou could use a BufferedReaderto read the file.

如果int每行开头的 是唯一的,则可以使用 aMap<Integer, String>来存储数据。这不会限制200可以从文件中读取的项目数量,如果您选择 aTreeMap作为实现,它将对它们进行排序(您可以接受 的自然顺序Integer或定义您自己的Comparator)。根据sethu 的建议,您可以使用 aBufferedReader来读取文件。

For example:

例如:

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

回答by Alexandre

I would personally do an IndexOf for the first space, then followed by a substring from 0 to the resulst of the IndexOf and a ParseInt to get the item number.

我个人会为第一个空间做一个 IndexOf,然后是一个从 0 到 IndexOf 的结果的子字符串和一个 ParseInt 来获取项目编号。

Then I would do a substring of IndexOf to end of the line, and do a Trim on the result for good measure.

然后我会做一个 IndexOf 的子字符串到行尾,并在结果上做一个 Trim 以获得良好的度量。

In your example, you also have no protection on your Array, if you have more than 200 lines in your file, you're gonna run out of space on your array. You should use a collection like ArrayList

在您的示例中,您的 Array 也没有任何保护,如果您的文件中有 200 多行,那么您的阵列空间就会用完。你应该使用一个像ArrayList

It would look something like this:

它看起来像这样:

First we change the declaration of your Array for ArrayList

首先,我们将 Array 的声明更改为 ArrayList

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

Second, we change your algorithm to use SubStringsand IndexOfand use ArrayList

其次,改变你要使用的算法SubStringsIndexOf和使用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);
     }
 }

If you want to go one step further, you could create a Classto represent your items and only have to use one ArrayListinstead of 2, but I think I covered your question already!

如果你想更进一步,你可以创建一个Class来代表你的项目,只需要使用一个ArrayList而不是 2,但我想我已经涵盖了你的问题!

回答by sethu

I wont write the code but I'll give you an algorithm:

我不会写代码,但我会给你一个算法:

  1. Use a BufferedReader to read each line of the file.
  2. Split each line into a String array based on space using String.split(" ")
  3. Go through each element of the String array and it to a StringBuffer until you reach a String which all numbers. There are many ways of checking if the String is all numbers. Check each character, use a regular expression and match the pattern, use the apache commons StringUtils class.
  4. If you have reached a number, then you know whatever you collected in the StringBuffer is the description. The ideal data structure to use in this case, is a TreeMap. Add the description as the key and the value as the price. You can sort the map and delete entries as you please.
  1. 使用 BufferedReader 读取文件的每一行。
  2. 使用 String.split(" ") 根据空间将每一行拆分为一个字符串数组
  3. 遍历 String 数组的每个元素并将其转换为 StringBuffer,直到找到一个包含所有数字的 String。有很多方法可以检查 String 是否都是数字。检查每个字符,使用正则表达式并匹配模式,使用 apache commons StringUtils 类。
  4. 如果您已经达到了一个数字,那么您就会知道您在 StringBuffer 中收集的任何内容都是描述。在这种情况下使用的理想数据结构是 TreeMap。添加描述作为键和值作为价格。您可以根据需要对地图进行排序和删除条目。

回答by Noroi

You can use some thing like this which would be much better

你可以使用这样的东西会更好

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

}