#include #include #include #include #include #include #include #include #include #include #include namespace po = boost::program_options; int main(int argc, char *argv[]) { 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), "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; 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 lettersUpper = letters; lettersUpper.toUpper(); icu::UnicodeString mustHaveLettersUpper = mustHaveLetters; mustHaveLettersUpper.toUpper(); long counter{0}; if (!std::filesystem::exists(wordsFile)) { std::cerr << "Datei existiert nicht: " << wordsFile << std::endl; return 1; } while (std::getline(infile, line)) { uline = icu::UnicodeString::fromUTF8(line); int length = uline.length(); if (length < wordLengthMin || length > wordLengthMax) continue; if (mustHaveLetters.length() > 0) { bool valid = true; 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 (startsCapital && i == 0) { if (lettersUpper.indexOf(ch) == -1) { valid = false; break; } } else if (letters.indexOf(ch) == -1 && lettersUpper.indexOf(ch) == -1) { valid = false; break; } } if (!valid) continue; } if (lowercase) { uline.toLower(); } words.push_back(uline); 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) { if (lectionLine.isEmpty()) lectionLine.append(words.at(distrib(rng))); else lectionLine.append(" " + words.at(distrib(rng))); } if (lectionLine.length() > lineLength) { lectionLine.retainBetween(0, lectionLine.lastIndexOf(" ") + 1); lectionLine.trim(); } std::cout << lectionLine << std::endl; } }