diff --git a/main.cpp b/main.cpp index 0b0cdd5..9808f0c 100644 --- a/main.cpp +++ b/main.cpp @@ -16,39 +16,66 @@ namespace po = boost::program_options; int main(int argc, char *argv[]) { - std::string letters; + icu::UnicodeString letters; + icu::UnicodeString mustHaveLetters; int wordLengthMin{1}; int wordLengthMax{1024}; int lineLength{60}; int numLines{4}; std::string wordsFile{"/usr/share/dict/ngerman"}; bool lowercase{false}; + bool startsCapital{false}; po::options_description desc("Erlaubte Optionen"); desc.add_options()("help,h", "Ausgabe der Hilfe")( - "characters,c", po::value(&letters), "Enthaltene Buchstaben")( - "min-length", po::value(&wordLengthMin), - "Minimale Wortlänge")("max-length", po::value(&wordLengthMax), "Maximale Wortlänge")( - "line-length", po::value(&lineLength), - "Maximale Zeilenlänge")("num-lines,n", po::value(&numLines), "Anzahl Zeilen")( - "lowercase", po::bool_switch(&lowercase), "Ausgabe nur klein geschrieben")( - "dictfile,d", po::value(&wordsFile), "Pfad zur Wörterbuchdatei"); + "characters,c", po::value(&letters), "Erlaubte Buchstaben")( + "must-have,m", po::value(&mustHaveLetters), + "Buchstaben, die im Wort vorhanden sein *müssen* (nur in Verbindung mit --characters; " + "Buchstaben müssen davon Subset sein.)")("min-length", po::value(&wordLengthMin), + "Minimale Wortlänge")( + "max-length", po::value(&wordLengthMax), + "Maximale Wortlänge")("line-length", po::value(&lineLength), "Maximale Zeilenlänge")( + "num-lines,n", po::value(&numLines), "Anzahl Zeilen")( + "dictfile,d", po::value(&wordsFile), "Pfad zur Wörterbuchdatei")( + "lowercase,l", po::bool_switch(&lowercase), + "Ausgabe nur klein geschrieben")("starts-capital,s", po::bool_switch(&startsCapital), + "Wort muss mit einem Großbuchstaben beginnen"); po::variables_map vm; - po::store(po::parse_command_line(argc, argv, desc), vm); - po::notify(vm); + try { + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + } catch (po::error &err) { + std::cerr << "Fehler beim Verarbeiten der Optionen:\n"; + std::cerr << err.what() << std::endl; + return 1; + } if (vm.contains("help")) { std::cout << desc << std::endl; return 1; } + if (mustHaveLetters.length() > 0) { + for (int i{0}; i < mustHaveLetters.length(); i++) { + auto ch = mustHaveLetters.charAt(i); + if (letters.indexOf(ch) == -1) { + std::cout + << "Die Buchstaben von --must-have müssen ein Subset von --characters sein." + << std::endl; + return 1; + } + } + } + std::ifstream infile(wordsFile); std::string line; icu::UnicodeString uline; std::vector words; - icu::UnicodeString ucLetters = icu::UnicodeString::fromUTF8(letters); - icu::UnicodeString ucLettersUpper = icu::UnicodeString::fromUTF8(letters).toUpper(); + icu::UnicodeString lettersUpper = letters; + lettersUpper.toUpper(); + icu::UnicodeString mustHaveLettersUpper = mustHaveLetters; + mustHaveLettersUpper.toUpper(); long counter{0}; if (!std::filesystem::exists(wordsFile)) { @@ -63,11 +90,30 @@ int main(int argc, char *argv[]) if (length < wordLengthMin || length > wordLengthMax) continue; - if (ucLetters.length() > 0) { + if (mustHaveLetters.length() > 0) { bool valid = true; - for (int i{0}; i < uline.length(); i++) { + for (int i{0}; i < mustHaveLetters.length(); i++) { + auto ch = mustHaveLetters.charAt(i); + auto chU = mustHaveLettersUpper.charAt(i); + if (uline.indexOf(ch) == -1 && uline.indexOf(chU) == -1) { + valid = false; + break; + } + } + if (!valid) + continue; + } + + if (letters.length() > 0) { + bool valid = true; + for (int i{0}; i < length; i++) { auto ch = uline.charAt(i); - if (ucLetters.indexOf(ch) == -1 && ucLettersUpper.indexOf(ch) == -1) { + if (startsCapital && i == 0) { + if (lettersUpper.indexOf(ch) == -1) { + valid = false; + break; + } + } else if (letters.indexOf(ch) == -1 && lettersUpper.indexOf(ch) == -1) { valid = false; break; } @@ -83,11 +129,17 @@ int main(int argc, char *argv[]) counter++; } + if (counter == 0) { + std::cout << "Keine Wörter mit den angegebenen Kriterien gefunden." << std::endl; + return 0; + } + std::cout << "Anzahl infrage kommender Wörter: " << counter << "\n" << std::endl; std::random_device rdev; std::mt19937 rng(rdev()); std::uniform_int_distribution distrib(0, words.size() - 1); + for (int i{0}; i < numLines; i++) { icu::UnicodeString lectionLine; while (lectionLine.length() < lineLength) {