【问题标题】:CaesarCipher program that output a text file in java在java中输出文本文件的CaesarCipher程序
【发布时间】:2019-03-19 04:34:10
【问题描述】:

我正在尝试构建一个程序,该程序采用文本文件,应用 CaesarCipher 方法并返回和输出文件。

import java.util.*;
import java.io.*;

class CaesarCipher
{
    public static void main (String [] args) throws FileNotFoundException {
        System.out.print("What is the input file name? ");
        Scanner keyboard = new Scanner(System.in);
        String fileName = keyboard.nextLine();
        Scanner inputFile = new Scanner (new File (fileName));
        String inputFileString = inputFile.toString();
        System.out.print("What is the input file name? ");
        int s = 4;
        System.out.println("Text  : " + inputFileString);
        System.out.println("Shift : " + s);
        System.out.println("Cipher: " + encrypt(inputFileString, s));
    }

    public static String encrypt(String inputFileString, int s) {
        StringBuilder result = new StringBuilder();

        for (int i=0; i< inputFileString.length(); i++) {
            if (Character.isUpperCase(inputFileString.charAt(i))) {
                char ch = (char)(((int)inputFileString.charAt(i) + s - 65) % 26 + 65);
                result.append(ch);
            }
            else {
                char ch = (char)(((int)inputFileString.charAt(i) + s - 97) % 26 + 97);
                result.append(ch);
            }
        }

        return result.toString();
    }
}

我有两个问题: 1-程序正在编译,但是当我运行它并输入文本文件名时,我收到此错误:

输入文件名是什么?文本 : java.util.Scanner[delimiters=\p{javaWhitespace}+][position=0][match 有效=假][需要输入=假][来源 关闭=false][跳过=false][组分隔符=\,][十进制 分隔符=.][正前缀=][负前缀=\Q-\E][正 后缀=][负后缀=][NaN字符串=\Q�\E][无穷大字符串=\Q∞\E]

2- 如何构造一个包含编码文本的新输出文件?

【问题讨论】:

    标签: java caesar-cipher


    【解决方案1】:

    您现有的代码没有实际上将输入文件读入String。您可以使用多种方法来执行此操作,例如Files.readAllLines(Path),它返回文件行的List&lt;String&gt;。流式传输,并使用行分隔符收集它。喜欢,

    String inputFileString = Files.readAllLines(new File(fileName).toPath()).stream()
                .collect(Collectors.joining(System.lineSeparator()));
    

    至于写入文件,看PrintStream(File)构造函数。

    【讨论】:

    • 有没有更简单的方法可以使用?
    • 当然……也许这个:String inputFileString = new String(Files.readAllBytes(Paths.get(fileName)));
    【解决方案2】:

    它与 StringBuilder 一起工作

    StringBuilder inputFileString = new StringBuilder();
            while (inputFile.hasNext()) {
                String x = inputFile.nextLine();
                inputFileString.append(x);
            }
    

    【讨论】:

      【解决方案3】:

      完整回答您的问题:

      1. 您并没有真正以正确的方式使用扫描仪。这是一个非常好的答案,它显示了how to convert an InputStream to a String 的几种方式。您唯一需要知道的是如何获取文件的 InputStream(检查下面的代码)。 作为旁注,您应该始终记住关闭您的资源。如果不再使用,请关闭您的 FileInputStream (more details here)。
          File file = new File("your/file/path/file.ending");
          try (FileInputStream fis = new FileInputStream(file)) {
              // your code here
          } catch (FileNotFoundException e){
              e.printStackTrace();
          }
      

      1. 还可以通过多种方式创建内容并将其写入文件。看看:How do I save a String to a text file using Java?

      总而言之,我创建了一个工作示例,使用稍微不同的方式来实现凯撒加密,并使用Files.lines(...) 读取文件内容并使用Files.write(...) 将加密内容写入新文件:

      import java.io.IOException;
      import java.nio.charset.StandardCharsets;
      import java.nio.file.Files;
      import java.nio.file.Path;
      import java.nio.file.Paths;
      import java.nio.file.StandardOpenOption;
      import java.util.Scanner;
      import java.util.stream.Stream;
      
      public class CaesarCipher {
      
          public static void main(String[] args) throws IOException {
              Scanner scanner = new Scanner(System.in);
      
              System.out.print("What is the input file name? ");
              Path filePath = Paths.get(scanner.nextLine());
      
              System.out.print("What is the output file name? ");
              Path encodedFilePath = Paths.get(scanner.nextLine());
      
              System.out.print("Caesar cipher offset? ");
              final int offset = Integer.parseInt(scanner.nextLine());
      
              // Retrieve a a stream of the input file, where each line is mapped using the encrypt function
              Stream<String> mappedFileStream = Files.lines(filePath).map(msg -> CaesarCipher.encrypt(msg, offset));
      
              // Write encrypted content to a new file using our mapped stream as an iterable
              Files.write(
                      encodedFilePath,
                      (Iterable<String>) mappedFileStream::iterator,
                      StandardCharsets.UTF_8,
                      StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
      
              // Decrypt the encoded file content and print it
              Files.lines(encodedFilePath)
                      .map((fileLine) -> CaesarCipher.decrypt(fileLine, offset))
                      .forEach(System.out::println);
          }
      
          public static String encrypt(String msg, int offset) {
              offset = offset % 26 + 26;
              StringBuilder encoded = new StringBuilder(msg.length());
              for (char i : msg.toCharArray()) {
                  if (Character.isLetter(i)) {
                      char base = Character.isUpperCase(i) ? 'A' : 'a';
                      encoded.append((char) (base + (i - base + offset) % 26));
                  } else {
                      encoded.append(i);
                  }
              }
              return encoded.toString();
          }
      
          public static String decrypt(String enc, int offset) {
              return encrypt(enc, 26 - offset);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-18
        相关资源
        最近更新 更多