从文本文件中读取字符而忽略新行中多余的空格的最佳方法是什么?



我正在阅读一个格式为 16x16 数独谜题的文本文件。

例如:

F7B-E-A-1--6---D  -91AF-0-85D7E4-C  05-69C---乙二醇-3-  -C-E-2-B--A-7860  E05---2F-7---1C-  -4-8-直流--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 个空格。 我尝试使用各种方式,如BufferedReader和FileInputStream,但无济于事。文本文件必须采用该格式,因为我的教授将使用这种格式使用自己的值进行测试。

我用于将文件放入数组列表的代码:

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

然后,我使用迭代器开始为 2D 数组赋值。当打印出网格时,它看起来很好,但是当检查单个值时,如网格[1][1],它不正确,因为它抛出的间距。

有没有办法逐个字符读取,但避免它放入 3 个空格来表示新行?

好吧,由于您只对十六进制字符和-真正感兴趣,因此您可以过滤掉其他所有内容。最简单的方法可能是替换:

current = (char)stream.read();

跟:

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

但是您可能需要摆弄错误条件以确保它是防弹的。

例如,检查输入循环完成后向records添加了多少元素。如果records.size()没有给你 256,则文件有问题。

这将消除文件中的所有格式问题,只有内容才重要(例如,如果需要,您可以在一行中提供所有 256 个字符(。

这遵循了稳健性原则,即"在你接受的东西上要自由,在你生产的东西上要具体"。


您可能还需要重新考虑从文件输入创建数组列表,然后从中构造二维数组的方法。在我看来,您可以使用类似(伪代码(直接创建 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")

这基本上只是从文件中读取所有字符,如果它们有效,则将它们直接添加到数组中。在添加之前,它会检查以确保您尚未填充拼图,并且在处理完所有字符后,它会检查以确保整个拼图已填充。

您提到要放入 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);
}
}

现在,您的 2d 数组将自动忽略末尾的空白,因为您逐行读取文件,并手动将值添加到 2d 数组中。

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()流中的内容时进行修剪,使这种转换变得非常容易:

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

如果你还没有掌握这个Java 8语法,你可以在Java 7风格中做基本上相同的事情:

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

最新更新