Palindrome-Finder: Rust-Programm zur Entdeckung rückwärts lesbaren Textes
Der Palindrome-Finder ist ein benutzerfreundliches Programm, das in einer Textdatei nach Wörtern sucht, die auch rückwärts gelesen einen Sinn ergeben. Die Idee hinter Palindromen ist faszinierend: Wörter wie „Otto“ oder Sätze wie „Renate bittet Tibetaner“ sind Beispiele für Texte, die in beide Richtungen gelesen denselben Sinn ergeben.
Das Programm benutzt clap zum Einlesen der Kommandozeilenargumente.
Ordnerstruktur
palindromefinder
├── Cargo.toml
├── src
│ └── main.rs
Cargo.toml
[package]
name = "palindromefinder"
version = "0.1.0"
edition = "2021"
description = "Findet Palindrome in Textdateien"
[dependencies]
clap = "3.2.25"
main.rs
use clap::{App, Arg}; // Importiere bestimmte Teile der clap-Bibliothek für die Verwendung
use std::collections::HashSet; // Importiere die HashSet-Datenstruktur für eindeutige Wörter
use std::error::Error; // Importiere das Error-Trait für Fehlerbehandlung
use std::fs::File; // Importiere die File-Struktur für Dateioperationen
use std::io::{self, BufRead}; // Importiere IO-Module für Ein- und Ausgabe
fn main() {
// Hauptfunktion, die das Programm startet
// Versuche, die `run`-Funktion auszuführen
if let Err(err) = run() {
// Wenn ein Fehler auftritt, gib eine Fehlermeldung aus und beende das Programm mit einem Fehlercode
eprintln!("Fehler: {}", err);
std::process::exit(1);
}
}
fn run() -> Result<(), Box<dyn Error>> {
// Die `run`-Funktion, die den Hauptteil des Programms enthält
// Definition der Kommandozeilenargumente mit Hilfe der `clap`-Bibliothek
let matches = App::new(env!("CARGO_PKG_NAME")) // Programmname aus Cargo.toml
.version(env!("CARGO_PKG_VERSION")) // Programmversion aus Cargo.toml
.about(env!("CARGO_PKG_DESCRIPTION")) // Programm-Beschreibung aus Cargo.toml
.author(env!("CARGO_PKG_AUTHORS")) // Autor(en) aus Cargo.toml
.arg(
Arg::new("inputfile")
.help("Legt die Eingabedatei fest, die gelesen werden soll")
.required(true) // Das Argument ist erforderlich
.index(1), // Es handelt sich um das erste Argument nach dem Programmnamen
)
.arg(
Arg::new("readme")
.short('r') // Kurze Option: -r
.long("readme") // Lange Option: --readme
.help("Zeigt an, was das Programm macht"), // Beschreibung der Option
)
.get_matches(); // Verarbeite die Kommandozeilenargumente
// Wenn die Option "--readme" angegeben ist, zeige eine Beschreibung des Programms und beende es
if matches.is_present("readme") {
println!("Dieses Programm findet in einer Textdatei Wörter, die auch rückwärts gelesen einen Sinn ergeben.");
println!("Es gibt nur Wörter aus, die mindestens 3 Buchstaben haben und sortiert sie aufsteigend.");
return Ok(()); // Beende das Programm erfolgreich
}
// Holen Sie den Namen der Eingabedatei aus den Kommandozeilenargumenten
let eingabedatei_name = matches.value_of("inputfile").unwrap();
// Versuche, die Eingabedatei zu öffnen
let datei = match File::open(eingabedatei_name) {
Ok(datei) => datei, // Wenn die Datei erfolgreich geöffnet wurde, fahre fort
Err(err) => {
if err.kind() == io::ErrorKind::NotFound {
// Wenn die Datei nicht gefunden wurde, gib eine Fehlermeldung aus
return Err(From::from(format!("Datei {} nicht gefunden", eingabedatei_name)));
} else {
// Andernfalls, wenn ein anderer Fehler auftritt, gib eine Fehlermeldung aus
return Err(From::from(err));
}
}
};
// Erzeuge einen Pufferleser, um die Datei Zeile für Zeile zu lesen
let leser = io::BufReader::new(datei);
// Erzeuge eine leere Menge (HashSet), um eindeutige Wörter zu speichern
let mut wort_set = HashSet::new();
// Durchgehe die Eingabedatei Zeile für Zeile
for zeile in leser.lines() {
let wort = zeile?; // Zeile in ein Wort umwandeln; ? behandelt Fehler
// Überprüfe, ob das Wort mindestens 3 Buchstaben hat
if wort.len() > 2 {
wort_set.insert(wort); // Füge das Wort zum Set hinzu
}
}
// Konvertiere das Set in einen Vektor und sortiere ihn aufsteigend
let mut sortierte_wörter: Vec<&String> = wort_set.iter().collect();
sortierte_wörter.sort();
// Durchgehe den sortierten Vektor und gib Wörter aus, die rückwärts gelesen einen Sinn ergeben
for wort in sortierte_wörter {
let umgekehrtes_wort: String = wort.chars().rev().collect();
if wort_set.contains(&umgekehrtes_wort) {
println!("{}", wort);
}
}
Ok(()) // Beende das Programm erfolgreich
}