00001 00002 #include <algorithm> 00003 #include <fstream> 00004 #include <iostream> 00005 #include <istream> 00006 #include <iterator> 00007 #include <locale> 00008 #include <ostream> 00009 #include <string> 00010 00015 template<class Char, class Traits = std::char_traits<Char> > 00016 class palindrome_tester 00017 { 00018 public: 00020 typedef std::basic_string<Char, Traits> string; 00021 00026 palindrome_tester(std::locale& locale) 00027 : locale_(locale), 00028 ctype_(std::use_facet<std::ctype<Char> >(locale_)) 00029 {} 00030 00035 bool isalpha(Char c) const { return ctype_.is(ctype_.alpha, c); } 00036 00043 Char lowercase(Char c) const { return ctype_.tolower(ctype_.toupper(c)); } 00044 00051 bool operator()(string const& str) 00052 const 00053 { 00054 if (str.empty()) 00055 return false; 00056 for (typename string::const_iterator first = str.begin(), last = str.end() - 1; first < last;) 00057 { 00058 if (not isalpha(*last)) 00059 --last; 00060 else if (not isalpha(*first)) 00061 ++first; 00062 else if (lowercase(*first) != lowercase(*last)) 00063 return false; 00064 else { 00065 ++first; 00066 --last; 00067 } 00068 } 00069 return not str.empty(); 00070 } 00071 00072 private: 00073 std::locale locale_; 00074 std::ctype<Char> const& ctype_; 00075 }; 00076 00077 int main(int argc, char** argv) 00078 { 00079 if (argc < 3) { 00080 std::cerr << "usage: " << argv[0] << "INPUT-FILE OUTPUT-FILE [LOCALE]\n"; 00081 return EXIT_FAILURE; 00082 } 00083 std::wifstream in(argv[1]); 00084 if (not in) { 00085 std::perror(argv[1]); 00086 return EXIT_FAILURE; 00087 } 00088 std::wofstream out(argv[2]); 00089 if (not out) { 00090 std::perror(argv[2]); 00091 return EXIT_FAILURE; 00092 } 00093 std::locale locale(argc >= 4 ? argv[3] : ""); 00094 palindrome_tester<wchar_t> is_palindrome(locale); 00095 in.imbue(locale); 00096 in.exceptions(in.badbit); 00097 out.imbue(locale); 00098 out.exceptions(out.badbit); 00099 00100 std::wstring line; 00101 while (std::getline(in, line)) 00102 if (is_palindrome(line)) 00103 out << line << L'\n'; 00104 }