- Main Page
- Namespaces
- Classes
- Files

# palindrome.cpp

Go to the documentation of this file.

    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 }