设为首页 加入收藏

TOP

1.3 第一个程序(2)
2013-10-07 13:17:58 来源: 作者: 【 】 浏览:65
Tags:1.3 一个 程序

1.3 第一个程序(2)

如果IDE没有自动保持窗口的打开状态,并且你没有发现任何选项或者设置来保持窗口打开,你可以通过在程序结束的右花括号处,或者在调试器允许设置断点的最近语句上设置一个断点,来强制窗口打开。

知道如何运行程序后,还应该知道输入什么数字来高效地测试程序。你如何测试list0101以确保它能正确地执行?

好,去做这些。程序正确运行了吗?

这很简单,不是吗?你应该尝试几种不同的顺序。不输入,运行程序。用1个数字来试试。用2个已经排好序的数字和2个已经反序的数字试试。试试多个排好序的数字。试试随机顺序的多个数字。试试多个反序的数字。

在完成这些探索之前,还有一个练习。这次,源文件更加复杂,它由一个专业的且很爱显摆的程序员编写。即使有人指导,也不要尝试去读程序,更不要尝试去弄懂程序。首先,不要模仿这个程序的编程(www.cppentry.com)风格。这个练习不是为你,而是为你的工具写的。目的是来查看编译器是否能够正确地编译程序,库实现是否有标准库的必要部分。这个测试虽然不会让编译器觉得备受折磨,但是它确实涉及一些高级C++(www.cppentry.com)特性。

因此不必费劲儿地去读这些代码,仅从本书网站上下载文件list0102.cpp就可以了,然后试着用你的工具编译和链接它。(列出程序的代码仅仅为那些不方便上网的读者。)如果编译器不能正确地编译并运行代码清单1-2,则需要更换它(更换编译器,而不是程序)。如果不更换,你可能在早期的课程中能侥幸通过,但是本书后面将会写一些相当复杂的程序,所以需要一个能够胜任的编译器。(另外,代码清单1-2和代码清单1-1做的基本是同样的事情。)

代码清单1-2 测试编译器

  1. /// 把标准输入按照字母表顺序进行排序。  
  2. /// 逐行读取文本,进行排序,并且把结果打印到标准输出。  
  3. /// 如果命令行输入了一个文件名,则从该文件中
    读入。否则,从标准输入读入。  
  4. /// 所有的输入都保存在内存中,所以不要用超过
    可用RAM大小的文件来测试这个程序。  
  5. ///  
  6. /// 比较采用命令行指定的区域设置,如果没有指
    定,则使用默认区域设置。  
  7.  
  8. #include <algorithm> 
  9. #include <cstdlib> 
  10. #include <fstream> 
  11. #include <iostream> 
  12. #include <iterator> 
  13. #include <locale> 
  14. #include <ostream> 
  15. #include <string> 
  16. #include <vector> 
  17.  
  18. /// 将文本行从参数in读入到参数iter。  
  19. /// @param in   输入流  
  20. /// @param iter  输出迭代器  
  21. template<class Ch, class Tr, class OutIter> 
  22. void read(std::basic_istream<Ch,Tr>& in, OutIter iter)  
  23. {  
  24.     std::basic_string<Ch,Tr> line;  
  25.     while (std::getline(in, line))  
  26.     {  
  27.         *iter = line;  
  28.         ++iter;  
  29.     }  
  30. }  
  31.  
  32. /// 排序函数对象  
  33. /// 参数化对象的字符类型,缓存区域设置,然后比较string。  
  34. template<typename Ch> 
  35. class sorter  
  36. {  
  37. public:  
  38.  
  39.     /// 构造排序对象,缓存输入的区域名。  
  40.     /// @param locname, 要缓存的区域名。  
  41.     sorter(Ch const* locname) :  
  42.         loc_(std::locale(locname)),  
  43.         collate_(std::use_facet<std::collate<Ch> >(loc_))  
  44.     {}  
  45.     /// 使用全局区域设置,构造默认排序对象。  
  46.     sorter() :  
  47.         loc_(std::locale()),  
  48.         collate_(std::use_facet<std::collate<Ch> >(loc_))  
  49.     {}  
  50.     /// 小于,用于标准算法的比较  
  51.     /// @param lhs 左操作数  
  52.     /// @param rhs 右操作数  
  53.     /// 在指定的区域设置下,如果参数lhs小于参数rhs,
    返回true,否则返回false  
  54.     template<typename Tr> 
  55.     bool operator()(const std::basic_string<Ch,Tr>& lhs,  
  56.                     const std::basic_string<Ch,Tr>& rhs)  
  57.         {  
  58.             return collate_.compare(lhs.data(),
    lhs.data()+lhs.size(),  
  59.                                   rhs.data(), 
  60. rhs.data()+rhs.size()) < 0;  
  61.         }  
  62. private:  
  63.     std::locale loc_;                     
    ///
    < cached locale  
  64.     const std::collate<Ch>& collate_;    
    ///
    < cached @c collate facet  
  65. };  
  66.  
  67. /// 通过推理模板参数,构造sorter对象。  
  68. /// @param name 传给sorter构造函数的区域名  
  69. /// @返回一个新的sorter对象  
  70. template<typename Ch> 
  71. sorter<Ch> make_sorter(Ch const * name)  
  72. {  
  73.     return sorter<Ch>(name);  
  74. }  
  75.  
  76. /// 主程序  
  77. int main(int argc, char* argv[])  
  78. try  
  79. {  
  80.     // 当出现不可恢复的输入错误时,比如硬盘故障,抛出异常。  
  81.     std::cin.exceptions(std::ios_base::badbit);  
  82.  
  83.     // 第一部分 把所有输入读入text,如果命
    令行输入了一个文件名,读取那个文件,  
  84.     // 否则读取标准输入。  
  85.     std::vector<std::string> text; ///< 把行文本保存在这儿  
  86.     if (argc < 2)  
  87.         read(std::cin, std::back_inserter(text));  
  88.     else  
  89.     {  
  90.         std::ifstream in(argv[1]);  
  91.         if (not in)  
  92.         {  
  93.             std::perror(argv[1]);          
    return EXIT_FAILURE;  
  94.         }  
  95.         read(in, std::back_inserter(text));  
  96.     }  
  97.  
  98.     // 第二部分 对text进行排序。第二个命令行参数
    代表区域名,控制排序顺序。如果存在,则使用它;  
  99.     // 如果不存在,则使用默认区域设置(从操作系统获取)。  
  100.     std::sort(text.begin(), text.end(), 
    make_sorter(argc 
    >= 3   argv[2] : "" ));  
  101.  
  102.     // 第三部分 打印排序后的text  
  103.     std::copy(text.begin(), text.end(),  
  104.               std::ostream_iterator<std::string>(std::cout, "\n"));  
  105. }  
  106. catch (std::exception& ex)  
  107. {  
  108.     std::cerr << "Caught exception: " << ex.what() << '\n';  
  109.     std::cerr << "Terminating program.\n";  
  110.     std::exit(EXIT_FAILURE);  
  111. }  
  112. catch (...)  
  113. {  
  114.     std::cerr << "Caught unknown exception
    type.\nTerminating program.\n";  
  115.     std::exit(EXIT_FAILURE);  

我知道你会看这些代码。尽管我已经事先警告过,你仍然情不自禁地阅读了它们,是不是?请记住,我故意用繁琐的方式编写这段程序仅仅是为了测试你的工具。当你读完本书时,就可以阅读并理解这个程序了。更重要的是,你可以更简单、更清晰地重写这段程序。学会跑前,先学会走。当你能够舒适地使用工具之后,就该开始学习C++(www.cppentry.com)了。下一步探索之旅将从阅读代码开始。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇1.1.2 Macintosh OS 9以及更早版.. 下一篇1.3 第一个程序(1)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: