程序不连续 运行

Program does not run continuously

我正在编写一个 ChatBot 程序,如果 ChatBot 没有信息来回答用户的问题,它会询问用户如何回答问题,然后将其存储在 txt 文件中。稍后,当提出另一个问题时,将从 txt 文件中检索信息,然后整个过程重新开始(或者至少应该重新开始)。

该程序可以运行,但是,在用户询问一次后,我再次按回车键进行第二次尝试,但没有任何反应。

这是我的代码:

import java.io.*;
import java.util.*;
import java.nio.file.*;
import java.util.stream.Stream;

public class Main {
  public static void main(String args[]) {
    System.out.println("Bot: Hello!! My name's HiBot! What's up?");
    System.out.print("You: ");
    Scanner input = new Scanner(System.in).useDelimiter("\n");
    String response = input.next();
    if (response.toLowerCase().contains("bye") || response.toLowerCase().contains("see ya")
        || response.toLowerCase().contains("gtg")) {
      System.out.println("Bot: Ok, see ya. Nice talking to you!");
    }
    processor(response);
  }

  public static void processor(String reply) {
    try {
      BufferedReader reader = new BufferedReader(new FileReader("convos.txt"));
      int count = 0;
      try {
        String line = reader.readLine();
        while (line != null) {
          count++;
          if (line.toLowerCase().contains(reply.toLowerCase())) {
            try (Stream<String> lines = Files.lines(Paths.get("convos.txt"))) {
              line = lines.skip(count).findFirst().get();
              System.out.println("Bot: " + line);
              recur();
            } catch (IOException e) {
              System.out.println("Bot: Something happened \n" + e);
            }
            reader.close();
            return;
          }
          reader.close();
        }
        System.out.println("Bot: Sorry, I'm dumb. How should I reply?");
        System.out.print("You: ");
        Scanner input = new Scanner(System.in).useDelimiter("\n");
        String response = input.next();
        teach(reply, response);
        recur();
      } catch (IOException e) {
        System.out.println("Bot: Something happened \n" + e);
      }
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    }
  }

  public static void teach(String context, String reply) {
    try {
      try {
        FileWriter learn = new FileWriter("convos.txt", true);
        PrintWriter out = new PrintWriter(learn);
        out.println(context + "\n" + reply);
        out.close();
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      }
    } catch (IOException e) {
      System.out.println("Bot: Something happened \n" + e);
    }
    System.out.println("Bot: Thank you for teaching me!! I'm smarter now!");
  }

  public static void recur() {
    int trickLoop = 1;
    while (trickLoop > 0) {
      System.out.print("You: ");
      Scanner input = new Scanner(System.in).useDelimiter("\n");
      String response = input.next();
      if (response.toLowerCase().contains("bye") || response.toLowerCase().contains("see ya")
          || response.toLowerCase().contains("gtg")) {
        System.out.println("Bot: Ok, see ya. Nice talking to you!");
        System.exit(0);
      }
      processor(response);
    }
  }
}

我也认为肯定有更好的方法来编写代码。有人有什么建议吗?

编辑:我有 convos.txt 但我没有在这里显示。

问题 1 :

最初文件不存在,您没有创建它。所以它给出了以下错误

Bot: Hello!! My name's HiBot! What's up?
You: hi
java.io.FileNotFoundException: convos.txt (The system cannot find the file specified)

第 2 期:

您正在使用 recur 方法进行递归,这在连续输入的情况下可能存在风险,因为您的资源不会立即关闭,并可能导致进一步的资源匮乏问题。 您可以简单地使用 infinite while 循环。

改进 1 :

您不认为一旦用户输入 bye/see ya/gtg 程序就应该关闭吗?

改进2:

在 main 方法中重复调用 string.toLowerCase()

改进 3 :

这一行 line = lines.skip(count).findFirst().get(); 可以导致 NoSuchElementException

我在下面的代码中添加了改进 2 和 3。

我在这里更新了下面的代码,它根据您在问题中的详细信息工作

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;
import java.util.stream.Stream;

public class Main {
    public static void main(String args[]) {
        System.out.println("Bot: Hello!! My name's HiBot! What's up?");
        while (true) {
            System.out.print("You: ");
            Scanner input = new Scanner(System.in).useDelimiter("\n");
            String response = input.next();
            String lowercaseResponse = response.toLowerCase();
            if (lowercaseResponse.contains("bye") || lowercaseResponse.contains("see ya")
                    || lowercaseResponse.contains("gtg")) {
                System.out.println("Bot: Ok, see ya. Nice talking to you!");
            }
            processor(response);
        }
    }

    public static void processor(String reply) {
        BufferedReader reader = null;
        try {
            File file = new File("convos.txt");
            if (file.createNewFile())
                System.out.println("Conversations file created");
            reader = new BufferedReader(new FileReader(file.getName()));
            int count = 0;
            String line = reader.readLine();
            while (line != null) {
                count++;
                if (line.toLowerCase().contains(reply.toLowerCase())) {
                    try (Stream<String> lines = Files.lines(Paths.get("convos.txt"))) {
                        line = lines.skip(count).findFirst().map(Object::toString).orElse("I don't know how to respond");
                        System.out.println("Bot: " + line);
                    } catch (IOException e) {
                        System.out.println("Bot: Something happened while reading conversation file \n" + e);
                    }
                    reader.close();
                    return;
                }
                line = reader.readLine();
            }
            reader.close();
            System.out.println("Bot: Sorry, I'm dumb. How should I reply?");
            System.out.print("You: ");
            Scanner input = new Scanner(System.in).useDelimiter("\n");
            String response = input.next();
            teach(reply, response);
        } catch (FileNotFoundException e) {
            System.out.println("Bot: File not found \n" + e);
        } catch (IOException e) {
            System.out.println("Bot: Something happened \n" + e);
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                System.out.println("Bot: Something happened while closing the file reader \n" + e);
            }
        }
    }

    public static void teach(String context, String reply) {
        try {
            try {
                FileWriter learn = new FileWriter("convos.txt", true);
                PrintWriter out = new PrintWriter(learn);
                out.println(context + "\n" + reply);
                out.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            System.out.println("Bot: Something happened \n" + e);
        }
        System.out.println("Bot: Thank you for teaching me!! I'm smarter now!");
    }
}

输出:For the first time

Bot: Hello!! My name's HiBot! What's up?
You: hi
Conversations file created
Bot: Sorry, I'm dumb. How should I reply?
You: hello
Bot: Thank you for teaching me!! I'm smarter now!
You: 
hi
Bot: hello
You: 

输出:When Convos.txt is created already

Bot: Hello!! My name's HiBot! What's up?
You: hi
Bot: hello
You: hi
Bot: hello
You: hi
Bot: hello
You: 

如果我遗漏了什么,请告诉我。

我看到这个问题是因为有人编辑了这个问题。

这是一项测试 运行。 “convos.txt”文件存在并且有几个响应/回复文本行。

Bot: Hello! My name's HiBot! What's up?
You: hi
Bot: Hi
You: how are you
Bot: Fine.  How are you?
You: Good
Bot: Sorry, I'm ignorant. How should I reply?
You: That's good to hear.
Bot: Thank you for teaching me a new reply! I'm smarter now!
You: bye
Bot: Ok, see ya. Nice talking to you!

我消除了多个 System.in Scanner 实例。在重组后的代码中,我只需要一个 Scanner 实例。您的代码中应该只有一个 System.in Scanner 实例。

我创建了一个单独的 ResponseMap class 来保存 HashMap 作为响应/回复文本。

我单独创建了一个FileHandler class来处理文本文件的读写。我一开始就将文件读入 Map 一次。我最后将 Map 写入文件一次。即使您有 10,000 行响应/回复,整个文件也应该很容易装入内存。

因为我将 Map 值设置为 String 个实例的 List,您可以为同一响应手动创建多个回复。这为聊天机器人增加了一点多样性。

这是完整的运行可用代码。

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;

public class ChatbotExample {
    
    public static void main(String[] args) {
        new ChatbotExample().runChatbot();
    }
    
    public void runChatbot() {
        Scanner scanner = new Scanner(System.in);
        String[] exitResponses = { "bye", "see ya", "gtg" };
        List<String> exitList = Arrays.asList(exitResponses);
        
        boolean running = true;
        System.out.println("Bot: Hello! My name's HiBot! What's up?");
        
        ResponseMap responseMap = new ResponseMap();
        FileHandler fileHandler = new FileHandler(responseMap);
        fileHandler.readFile();
        
        while (running) {
            System.out.print("You: ");
            String response = scanner.nextLine();
            String lowercaseResponse = response.toLowerCase();
            if (exitList.contains(lowercaseResponse)) {
                System.out.println("Bot: Ok, see ya. Nice talking to you!");
                running = false;
            } else {
                generateReply(scanner, responseMap, lowercaseResponse);
            }
        }
        
        fileHandler.writeFile();
        scanner.close();
    }

    private void generateReply(Scanner scanner, ResponseMap responseMap, 
            String lowercaseResponse) {
        String text = responseMap.getResponse(lowercaseResponse);
        if (text == null) {
            System.out.println("Bot: Sorry, I'm ignorant. How should I reply?");
            System.out.print("You: ");
            String reply = scanner.nextLine();
            responseMap.addResponse(lowercaseResponse, reply);
            System.out.println("Bot: Thank you for teaching me a new reply! "
                    + "I'm smarter now!");
        } else {
            System.out.println("Bot: " +  text);
        }
    }
    
    public class FileHandler {
        
        private final File file;
        
        private final ResponseMap responseMap;
        
        private final String separator;
        
        public FileHandler(ResponseMap responseMap) {
            this.responseMap = responseMap;
            this.separator = " ;;; ";
            this.file = new File("convos.txt");
            createFile(this.file);
        }

        private void createFile(File file) {
            try {
                if (file.createNewFile()) {
                    System.out.println("Conversations file created");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void readFile() {
            try {
                BufferedReader reader = new BufferedReader(
                        new FileReader(file));
                
                String line = reader.readLine();
                while (line != null) {
                    String[] parts = line.split(separator);
                    responseMap.addResponse(parts[0], parts[1]);
                    line = reader.readLine();
                }
                
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        public void writeFile() {
            try {
                FileWriter writer = new FileWriter(file, false);
                PrintWriter output = new PrintWriter(writer);
                Map<String, List<String>> responses = responseMap.getResponses();
                Set<String> responseSet = responses.keySet();
                Iterator<String> iterator = responseSet.iterator();
                
                while (iterator.hasNext()) {
                    String key = iterator.next();
                    List<String> text = responses.get(key);
                    for (String reply : text) {
                        String s = key + separator + reply;
                        output.println(s);
                    }
                }
                
                output.flush();
                output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    }
    
    public class ResponseMap {
        
        private final Map<String, List<String>> responses;
        
        private final Random random;
        
        public ResponseMap() {
            this.responses = new HashMap<>();
            this.random = new Random();
        }
        
        public Map<String, List<String>> getResponses() {
            return responses;
        }

        public String getResponse(String key) {
            List<String> possibleResponses = responses.get(key);
            if (possibleResponses == null) {
                return null;
            } else {
                int index = random.nextInt(possibleResponses.size());
                return possibleResponses.get(index);
            }
        }
        
        public void addResponse(String key, String text) {
            List<String> possibleResponses = responses.get(key);
            if (possibleResponses == null) {
                possibleResponses = new ArrayList<>();
                responses.put(key, possibleResponses);
            }
            possibleResponses.add(text);
        }
    }

}