【问题标题】:Preserving line breaks and spacing in file IO在文件 IO 中保留换行符和间距
【发布时间】:2012-10-22 16:09:17
【问题描述】:

我正在处理一个非常巧妙的问题挑战,涉及从 .txt 文件中读取单词。该程序必须允许读取任何 .txt 文件,因此程序无法预测它将处理哪些单词。

然后,它将这些词变成它们的“Pig Latin”对应词,并将它们写入一个新文件。这个问题还有很多要求,但我只想说,我已经解决了每个部分,保存一个......当打印到新文件时,我无法保持行距。也就是说,如果第 1 行有 5 个单词,然后有一个 break,第 2 行有 3 个单词和一个 break……对于新文件也必须如此。就目前而言,一切正常,但所有转换后的单词都一个接一个地列出来。

我有兴趣学习这个,所以如果你们都想在你的答案中表现得害羞,我可以。虽然我已经在这工作了 9 个小时,所以“半腼腆”也会受到影响 :) 请密切注意代码中的“while”语句,这是文件 IO 操作发生的地方。我想知道是否需要使用扫描仪中的 nextLine() 命令,然后从中生成一个字符串……然后从 nextLine() 字符串中生成子字符串,以一次一个地转换单词。子字符串可能是拆分或标记,或其他东西 - 我不清楚这部分和标记尝试给我编译器错误异常“java.util.NoSuchElementException” - 我似乎不理解对拆分命令的正确调用。我尝试了类似 String a = scan.nextLine() 的东西,其中“scan”是我的扫描仪变量。然后尝试了 String b = a.split() 不行。无论如何,这是我的代码,看看你能不能弄清楚我错过了什么。

这是代码,非常感谢Java大神....

import java.util.*;
import javax.swing.*;
import java.io.*;
import java.text.*;

public class PigLatinTranslator
{
    static final String ay = "ay"; // "ay" is added to the end of every word in pig latin

    public static void main(String [] args) throws IOException
    {
        File nonPiggedFile = new File(...);
        String nonPiggedFileName = nonPiggedFile.getName();
        Scanner scan = new Scanner(nonPiggedFile);  

        nonPiggedFileName = ...;

        File pigLatinFile = new File(nonPiggedFileName + "-pigLatin.txt"); //references a file that may or may not exist yet

        pigLatinFile.createNewFile();
        FileWriter newPigLatinFile = new FileWriter(nonPiggedFileName + "-pigLatin.txt", true);
        PrintWriter PrintToPLF = new PrintWriter(newPigLatinFile);

        while (scan.hasNext()) 
        {
            boolean next;
            while (next = scan.hasNext()) 
            {
                 String nonPig = scan.next();
                 nonPig = nonPig.toLowerCase();
                 StringBuilder PigLatWord = new StringBuilder(nonPig);
                 PigLatWord.insert(nonPig.length(), nonPig.charAt(0) );
                 PigLatWord.insert(nonPig.length() + 1, ay);
                 PigLatWord.deleteCharAt(0);
                 String plw = PigLatWord.toString();

                 if (plw.contains("!") )
                 {
                     plw = plw.replace("!", "") + "!";
                 }

                 if (plw.contains(".") )
                 {
                     plw = plw.replace(".", "") + ".";
                 }

                 if (plw.contains("?") )
                 { 
                     plw = plw.replace("?", "") + "?"; 
                 }

                 PrintToPLF.print(plw + " ");
            }

            PrintToPLF.close();
        }
    }
}

【问题讨论】:

  • 还有..你的问题是什么?如果它在某处,请添加一个“?”到最后。
  • 对不起,我想我的标题已经说明了一切,但由于我坚持解决方案,所以我很容易在我感知到的问题上犯错。问题是如何从用户提交的文件中读取单词,然后更改这些单词,然后将更改后的单词打印到新文件中……而……这是主要问题……保留换行符,以便所有单词第一行停留在第一行,第 2 行的原始文档中的单词进入第 2 行的新文件,依此类推。我的代码可以工作,但会一个接一个地放置所有新单词,而不考虑换行符。
  • @reeltempting:您的代码不起作用。它不能正确处理两个辅音词(即“what”)和元音词(即“about”)
  • 只是为了以后可能会来的人添加一个答案。上述代码的问题......至少与问题有关的是,我不应该使用 hasNext() - 而我应该使用 NextLine() 读取文件并一次抓取文件一行一次一个词。

标签: java io tokenize substring


【解决方案1】:

使用BufferedReader,而不是Scannerhttp://docs.oracle.com/javase/6/docs/api/java/io/BufferedReader.html

我将这部分作为原始海报的练习,一旦您知道要使用的正确课程就很容易! (希望你能学到一些东西,而不是复制粘贴我的代码)。

然后将整行传递给这样的函数:(请注意,这不能正确处理引号,因为它将所有非撇号标点符号放在单词的末尾)。它还假设标点符号应该放在单词的末尾。

private static final String vowels = "AEIOUaeiou";
private static final String punct = ".,!?";

public static String pigifyLine(String oneLine) {
   StringBuilder pigified = new StringBuilder();
   boolean first = true;
   for (String word : oneLine.split(" ")) {
       if (!first) pigified.append(" ");
       pigified.append(pigify(word));
       first = false;
   }
   return pigified.toString();
}

public static String pigify(String oneWord) {
    char[] chars = oneWord.toCharArray();
    StringBuilder consonants = new StringBuilder();
    StringBuilder newWord = new StringBuilder();
    StringBuilder punctuation = new StringBuilder();
    boolean consDone = false; // set to true when the first consonant group is done

    for (int i = 0; i < chars.length; i++) {
        // consonant
        if (vowels.indexOf(chars[i]) == -1) {
            // punctuation
            if (punct.indexOf(chars[i]) > -1) {
                punctuation.append(chars[i]);
                consDone = true;
            } else {
                if (!consDone) { // we haven't found the consonants
                    consonants.append(chars[i]);
                } else {
                    newWord.append(chars[i]);
                }
            }
        } else {
            consDone = true;
            // vowel
            newWord.append(chars[i]);
        }
    }

    if (consonants.length() == 0) {
        // vowel words are "about" -> "aboutway"
        consonants.append("w");
    } 
    consonants.append("ay");

    return newWord.append(consonants).append(punctuation).toString();
}

【讨论】:

    【解决方案2】:

    您可以尝试将每行的字数存储在一个单独的数据结构中,并以此作为编写文件时何时移至下一行的指南。

    我特意为你做了这个半模糊的,但可以根据要求详细说明。

    【讨论】:

    • 理论上我不知道文件中有什么。它旨在改变单词并吐出它们。因此,如果我不知道文件中的内容,您的计划是否仍然有效?我们被允许假设文件中没有数字,如果是,我们只需让程序像一个单词一样更改它们。
    • 当然可以。您需要在读取文件时填充该列表。我假设这些单词由一些分隔符(如空格)分隔,所以你只需阅读,记录该行的字数,将其保存,写入,下一行。基本上,只需在阅读时以某种方式跟踪每一行的单词。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-20
    • 2018-01-09
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 2013-07-27
    相关资源
    最近更新 更多