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 }