【问题标题】:How to read a text file with a mix of int and strings delimited by space and store each into arrays如何读取由空格分隔的 int 和字符串混合的文本文件并将每个文件存储到数组中
【发布时间】:2012-04-04 02:02:39
【问题描述】:

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

  • 1642纯羊毛T恤
  • 613 红色系带鞋
  • 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);

}

或者有更好的方法吗?我读过一些关于模式和正则表达式的帖子,但也不知道如何使用它。

谢谢!

【问题讨论】:

  • 如果您觉得使用数据库不适合您要解决的问题,我的建议是将您的输入文件格式重构为更具代表性的格式,例如JSONXML。固定数组索引适用于小型测试用例,但它不够健壮,无法优雅地处理输入数据结构中的更改。作为奖励,JSON 将为您处理类型识别和deserialization
  • “大约 200 项”?如果您不确定长度,我建议您使用列表。此外,我建议创建一个 Item 对象来存储数据,使 List 存储 。正则表达式是提取单个部分的方法,但我不太擅长,所以我不能给你一个模式
  • “1234 Official 39ers Jersey”之类的物品需要处理吗?
  • @Thomas:不,只有描述中的字符 MrGomez:谢谢,但听起来超出了我微不足道的脑容量 x(ggrigery:我会查看列表,谢谢
  • @hugTears 我一直在尝试解决正则表达式模式,但无济于事。我认为它有点类似于(\d+\D+)。如果您将regex 标签添加到您的问题中,正则表达式专家可能会经过并帮助您。祝你好运:)

标签: java regex arrays input java.util.scanner


【解决方案1】:

你可以用这样的东西会好很多

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

}

【讨论】:

    【解决方案2】:

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

    然后我会在行尾做一个 IndexOf 的子字符串,并对结果做一个 Trim 以便更好地衡量。

    在您的示例中,您的阵列也没有保护,如果您的文件中有超过 200 行,那么您的阵列空间将用完。你应该使用像ArrayList这样的集合

    看起来像这样:

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

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

    其次,我们将您的算法更改为使用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);
         }
     }
    

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

    【讨论】:

    • 谢谢,但我在 ArrayList 的声明中收到“令牌中的语法错误”:S
    【解决方案3】:

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

    itemArr[n] = item;
    

    会抛出一个ArrayIndexOutOfBoundsException

    如果每行开头的int 是唯一的,您可以使用Map&lt;Integer, String&gt; 来存储数据。这不会限制 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));
    }
    

    【讨论】:

      【解决方案4】:

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

      1. 使用 BufferedReader 读取文件的每一行。
      2. 使用 String.split(" ") 将每一行根据空间拆分成一个字符串数组
      3. 遍历 String 数组的每个元素并将其放入 StringBuffer,直到您到达包含所有数字的 String。有很多方法可以检查字符串是否全是数字。检查每个字符,使用正则表达式并匹配模式,使用 apache commons StringUtils 类。
      4. 如果您达到了一个数字,那么您就知道在 StringBuffer 中收集的任何内容都是描述。在这种情况下使用的理想数据结构是 TreeMap。将描述添加为键,将值添加为价格。您可以随意对地图进行排序和删除条目。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-20
        • 2017-10-19
        • 1970-01-01
        • 1970-01-01
        • 2014-12-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多