/****************************************************************************** * This program implements a spell checker. * * Copyright © 2021 Richard Lesh. All rights reserved. *****************************************************************************/ #undef NDEBUG #include "Utils.hpp" #include #include #include #include #include #include #include #include std::locale utf8loc(std::locale(), new std::codecvt_utf8); using namespace Utils; using namespace std; static unordered_map DICTIONARY = {}; void read_dictionary_file(wstring filespec) { wifstream ifh(filesystem::path(filespec).c_str()); if (!ifh.good()) { throw ios_base::failure(Utils::wchar_to_UTF8(L"Problem opening dictionary file!")); } ifh.imbue(utf8loc); wstring line; while (getline(ifh, line)) { DICTIONARY[Utils::tolower(line)] = true; } ifh.close(); } void spellcheck_file(wstring filespec) { wifstream ifh(filesystem::path(filespec).c_str()); if (!ifh.good()) { throw ios_base::failure(Utils::wchar_to_UTF8(L"Problem opening input file!")); } ifh.imbue(utf8loc); wstring line; unordered_map misspelled_words = {}; while (getline(ifh, line)) { vector matches = Utils::regex_findall(wregex(L"\\w+"), line); if (Utils::defined(matches)) { for (wstring s : matches) { wstring const SLOWER = Utils::tolower(s); if (!DICTIONARY.count(SLOWER)) { misspelled_words[SLOWER] = true; } } } } const vector sortedkeys = Utils::sort(Utils::keys(misspelled_words)); for (auto s : sortedkeys) { wcout << s << endl; } ifh.close(); } int main(int argc, char **argv) { setlocale(LC_ALL, "en_US.UTF-8"); wcout.imbue(utf8loc); wcin.imbue(utf8loc); if (argc != 3) { wcout << L"Syntax: " << Utils::UTF8_to_wstring(argv[0]) << L" {dictionary} {filename}" << endl; exit(1); } wstring dictionary_file = Utils::UTF8_to_wstring(argv[1]); wstring filename = Utils::UTF8_to_wstring(argv[2]); try { read_dictionary_file(dictionary_file); spellcheck_file(filename); } catch (ios_base::failure ex) { wcout << L"Error: " << Utils::exceptionMessage(ex) << endl; } return 0; }