代码之家  ›  专栏  ›  技术社区  ›  NotSoAdvanced

在忽略新行的额外空格的情况下,从文本文件中读入字符的最佳方法是什么?

  •  0
  • NotSoAdvanced  · 技术社区  · 7 年前

    我正在阅读一个16x16数独拼图格式的文本文件。

    F7B-E-A-1--6---D  
    -91AF-0-85D7E4-C  
    05-69C---B-EA-3-  
    -C-E-2-B--A-7860  
    E05---2F-7---1C-  
    -4-8-DC--E-593--  
    -29---1-D--A-04-  
    D67-A-98----B-F-  
    9B-D-130C8--F5A-  
    8F4569EA7D--CB--  
    6A---745BFE-12D9  
    7--1DBFC-A-04--E  
    5-F9C-61240D-7E-  
    A--7-F-DE-580-2-  
    --0-5E7-F63C--14  
    CE640-----7B5D9F
    

    我试图将这些值放入2D字符数组中,但当遇到第3行末尾时,似乎包含空格。

    我将文件放入ArrayList的代码:

    private static ArrayList readFile(File filename)
    {
        ArrayList records = new ArrayList();
        try
        {
            FileInputStream stream = new FileInputStream(filename);
    
            char current;
            while(stream.available() > 0)
            {
                current = (char)stream.read();
                records.add(current);
            }
            stream.close();
            return records;
        }
        catch (Exception e)
        {
            System.err.format("Exception occurred trying to read '%s'.", filename);
            return null;
        }
    }
    

    有没有办法一个字符一个字符地读取,但要避免用3个空格来表示新行?

    3 回复  |  直到 7 年前
        1
  •  3
  •   Tony Ng Wei Shyang    7 年前

    您提到要放入2D字符数组,因此可能希望忽略位置>15 :

    char[][] sudoku = new char[16][16];
    Scanner sc = new Scanner(filename);
    String[] temporary = new String[16];
    int counter = 0;
    
    while(sc.hasNext){
        temporary[counter] = sc.nextLine();
        counter ++;
    }
    
    for(int i = 0; i < 16; i++){
        for(int j = 0; j < 16; j++){
            sudoku[i][j] = temporary[i].charAt(j);
        }
    }
    

        2
  •  2
  •   paxdiablo    7 年前

    既然你只对十六进制字符感兴趣 -

    current = (char)stream.read();
    

    current = (char)stream.read();
    while ("0123456789ABCDEF-".indexOf(current) < 0)
        current = (char)stream.read();
    

    但您可能需要处理错误条件,以确保它是防弹的。

    records 一旦输入循环完成。如果 records.size()

    这将消除 全部的

    这遵循了稳健性原则“对你接受的东西要自由,对你生产的东西要具体”。


    您可能还需要重新考虑从文件输入创建数组列表,然后从中构造二维数组的方法。在我看来,你可以直接用(伪代码)创建2D数组:

    def readPuzzle(file) -> (array, error)
        set puzzle to new char[16][16]
        set row to 0, col to 0
    
        get next character from file to current
        while read okay:
            if current in "0123456789ABCDEF-":
                if row is 16:
                    return (puzzle, "too many entries in file")
                puzzle[row][col] = current
                increment col
                if col is 16:
                    increment row
                    set col to 0
        if row is not 16:
            return (puzzle, "not enough entries in file")
        return (puzzle, "okay")
    

    并将其直接添加到数组中(如果有效)。在添加之前,它会检查以确保您尚未填充拼图,并且在处理完所有字符后,它会进行检查以确保 整体 谜题被填满了。

        3
  •  1
  •   dimo414    7 年前

    String.trim()

    private static void trimAllStrings(List<String> list) {
      for (int i = 0; i < list.size(); i++) {
        list.put(i, list.get(i).trim());
      }
    }
    

    或者,您可以在阅读Java 8中的内容时进行修剪 Files.lines() stream使这种转换非常容易:

    List<String> trimmedLines = Files.lines(myfile, StandardCharsets.UTF_8)
        .map(String::trim).collect(Collectors.toList());
    

    ArrayList<String> list = new ArrayList<>();
    for (String line : Files.readAllLines(myfile, StandardCharsets.UTF_8)) {
      list.add(line.trim());
    }