《C++ Primer》学习笔记散记……(未完待完篇......)

  前面的话:C++Primer并不适合“初学者”,初学者还是看《C++Primer Plus》我没有看过,但道听途说适合初学者,学习C++的艰辛真是一言难尽!

    其实《C++Primer》这本书我一直在看,来来回回,反反复复,因为心浮气躁所以收效不大,其实如果你自认为是理所当然的事情其实你可能并不知道地很清楚,所以我决心从头再看一遍,我要把里面的程序和习题从头到尾彻彻底底地执行和剖析一遍,并写下心得和笔记,之所以这样一个是为我自己,一个是为了因为学习C++ Primer而非常痛苦的人们,我曾经听过一位博士讲的C++课程,我感觉是在浪费宝贵的时间,因为根据我的经验,往往是教材的每章的最后部分才是实际中最有用的部分,而在学校里就被略过了,因为考试不会考。因为是自学,所以在遇到问题时往往没有人给你回答,网路上的C++ Primer学习笔记太过简略,没有多大的价值,在第五章之前,我一直没有遇到太大的疑问,我跳过了第二章,在学完了后面的章节,才有资格去看第二章。为了更好的剖析C++ Primer,我手上的参考书籍是,在遇到问题时我都会翻看以下这些书籍:
《The C++ Programming Language》by Bjarne Stroustrup
《The C++ Standard Library》by Nicolai M.Josuttis
《effective C++》by Mayer
《More effective C++》by Mayer
《C++ STL 中文版》by P.J.Plauger
《掌握标准C++类》by Cameron Hughes ,Tracey Hughes
《STL 进行C++编程》by David etc
《Think in C++》by Bruce
《C++ 大学教程》by H.M ,P.D
 ......
 ......
 ......
第五章:
ilist类的编译
    第○,改.c为.cpp;

    第一,应该把#include “iostream.h”全部改成“ #include "iostream",同样
 fstream.h -> fstream; stddef.h -> cstddef ,对于别的程序可能要附加相应的
文件头,这要看程序使用了什么特色了;

    第二,增加using namespace std到预处理器后面;

    第三,去掉 allocator

    第四,g++ -o ilist.exe  ilist.cpp ilistmain.cpp ;

成功了!

5.11 P202,关于_current
    _current是指向一个ilist_item类的指针,意义是总是指向当前的活动的ilist_item项,如果删除了ilist的头,而_current还是指向链表头那就大事不妙了,所以对remove和remove_front要进行修改。


第六章
main0.cpp程序的注释
//增加#include <iterator>到程序头
//在运行栏输入:g++ -o main0.exe main0.cpp
#include <algorithm>
#include <string>
#include <vector>
#include <utility>

#include <iostream>
#include <fstream>
#include <iterator>  //因为运用了ostream_iterator模板对象所以这是必须的,而原程序没有包含
#include <cstddef>

#include <ctype.h>

using namespace std; //为了方便,所以显式指定名字空间是标准名字空间

extern vector<string> *retrieve_text(); //这句是说retrieve_text在某处已经定义了,让编译程序自己去找,main会用到
                                                          

int main()
{
 vector<string> *text_file = retrieve_text(); //text_file是指向一个由string组成的vector的指针,由retrieve_text返回


 cout << "----------- about to generate text read --------------/n";
 ostream_iterator< string > output( cout, "/n" ); 
//这句是说output是一个输出流迭代器,此迭代器锁定了string类型,与cout标准输出对象绑定,大部分情况下是显示器,对于读到的每一行都插入/n 换行符      
        copy( text_file->begin(), text_file->end(), output );//拷贝所有的text_file到标准输出,换句话说就是把text_file插入到标准输出

 return 0;
}

//我先大体的叙述一下retrieve_text函数是做什么和怎么做的,此函数读取输入的文本文件中的每一行,一行一行地记录其内容,为什么这么说呢,你想想看-它把输入的文本文件一行一行的读出来,看做string,用push_back放在了vector中,简言之vector中的0号元素就是text文件的第一行,以此类推。
   它是如何做的呢?首先它构建了一个ifstream对象,这个对象的本身代表输入文本文件自己,接着getline登场,注意getline有两个一个是为流提供的getline,一个是在<string>中为string提供的getline,此处用的是后者。getline顾名思义,就是得到文件的一行,其实那倒也不一定,取决于getline的第三个参数,默认的参数就是“/n",“/n"意味着getline就是名副其实的get line,接下来vector的push_back粉墨登场,它把从getline获取的每一行做为string放进vector容器中,此时vector的大小会自动的加一。其它的部分很简单,就此略过。
vector<string>*
retrieve_text()
{
 string file_name;
 
 cout << "please enter file name: ";
 cin  >> file_name;

 ifstream infile( file_name.c_str(), ios::in );//infile是一个ifstream //对象,当然ifstream是一个由typedef定义的模板类,它锁定了char类型做为参量,构造函数需要一个const char*,ios::in的意义是首先ios是一个锁定char类型的流模板,而in是告诉流要为输入而打开一个文件
 if ( !infile ) {
  cerr << "oops! unable to open file "
       << file_name << " -- bailing out!/n";
  exit( -1 );
 }
 else if( infile.eof() ){
//我自己的修改,如果输入的文本文件是空的,则退出不做这样的处理会在这样的情况下崩溃
  cerr << "please don't input a empty file";
  cout << "/n";
  exit( -1 );
 }

 vector<string> *lines_of_text = new vector<string>;
        string textline;

        typedef pair<string::size_type, int> stats;
        stats maxline;
 int   linenum = 0;

        while ( getline( infile, textline, '/n' ))
 {
  cout << "line read: " << textline << "/n";

    if ( maxline.first < textline.length() )
   {
       maxline.first = textline.length();
       maxline.second = linenum;
   }

  lines_of_text->push_back( textline );
  linenum++;
 }

 cout << "/n";
        cout << "number of lines: "
             << lines_of_text->size() << "/n";

 cout << "maximum length: " 
      << maxline.first << "/n";

        cout << "longest line: "   
      << (*lines_of_text)[ maxline.second ] << "/n";
 
 return lines_of_text;
}

/*
dumbo[107] ~/d.stdlib => a.out
please enter file name: alice_emma

line read: Alice Emma has long flowing red hair. Her Daddy says
line read: when the wind blows through her hair, it looks almost alive,
line read: like a fiery bird in flight. A beautiful fiery bird, he tells her,
line read: magical but untamed. "Daddy, shush, there is no such thing,"
line read: she tells him, at the same time wanting him to tell her more.
line read: Shyly, she asks, "I mean, Daddy, is there?"

number of lines: 6
maximum length: 66
longest line: like a fiery bird in flight. A beautiful fiery bird, he tells her,


main1.cpp程序的注释 
#include <algorithm>
#include <string>
#include <vector>
#include <utility>
#include <iterator>

#include <iostream>
#include <fstream>

#include <cstddef>

using namespace std;

typedef pair<short,short>           location;
typedef vector<location>  loc;
typedef vector<string>    text;
typedef pair<text*,loc*>            text_loc;

extern vector<string> *retrieve_text();
extern text_loc *separate_words( const vector<string>* );
extern void display_text_locations( text_loc* );

int main()
{
 vector<string>   *text_file      = retrieve_text();
        text_loc      *text_locations = separate_words( text_file );

 ostream_iterator< string > output( cout, "/n" );

 cout << "----------- about to generate text read --------------/n";
        copy( text_file->begin(), text_file->end(), output );

 cout << "----------- about to word and location data --------------/n";
 display_text_locations( text_locations );

 return 0;
}

vector<string>*
retrieve_text()
{
 string file_name;
 
 cout << "please enter file name: ";
 cin  >> file_name;

 ifstream infile( file_name.c_str(), ios::in );
 if ( !infile ) {
  cerr << "oops! unable to open file "
       << file_name << " -- bailing out!/n";
  exit( -1 );
 }
 else cout << "/n";

 vector<string> *lines_of_text = new vector<string>;
        string textline;

        typedef pair<string::size_type, int> stats;
        stats maxline;
 int   linenum = 0;

        while ( getline( infile, textline, '/n' ))
 {
  cout << "line read: " << textline << "/n";

  if ( maxline.first < textline.length() )
  {
       maxline.first = textline.length();
       maxline.second = linenum;
  }

  lines_of_text->push_back( textline );
  linenum++;
 }

 cout << "/n";
        cout << "number of lines: "
             << lines_of_text->size() << "/n";

 cout << "maximum length: " 
      << maxline.first << "/n";

        cout << "longest line: "   
      << (*lines_of_text)[ maxline.second ] << "/n";
 
 return lines_of_text;
}

text_loc*
separate_words( const vector<string> *text_file )
{
        // ok: now have all the lines. wish to grab the
        // individual words: look for blanks:

        vector<string>   *words     = new vector<string>;
 vector<location> *locations = new vector<location>;
//对于书中给出的输入文本文件text_file->size()应该是6,因为string vector就是6行
//所以对于for循环就是for(short line_pos = 0;line_pos < 6; line_pos++),共循环6次来迭
//代每一行

        for ( short line_pos = 0; line_pos < text_file->size(); line_pos++ )
        {
  short  word_pos = 0;
                string textline = (*text_file)[ line_pos ];

                cout << "textline: " << textline << endl;

                string::size_type eol = textline.length(); //这是一行的长度,连空格和符号也别放过
                string::size_type pos = 0, prev_pos = 0;
                                                                        //好的,现在让我们开始数数儿吧。

                while (( pos = textline.find_first_of( '  ', pos )) != string::npos )
                {
// 例如:对于第一行 :Alice Emma has long flowing red hair. Her Daddy says
// eol: 52 pos: 5 line: 0 word: 0 substring: Alice 意思是说,数到52,第一行结束,数到第5时
//出现个空格(记住Lippman先生说过要从0开始数),是第0行,此时标记出第一个词,
//位置是0,内容是Alice,再把Alice放进words中,words是一个string vector,想想为什么
//要放进vector中,因为要给单独的词一个代号比如0号,1号,2号.......

                      cout << "eol: "  << eol << " "
        << "pos: "  << pos << " "
        << "line: " << line_pos << " "
        << "word: " << word_pos << " "
                             << "substring: "
                             << textline.substr( prev_pos, pos-prev_pos )
        << "/n";

                        words->push_back( textline.substr( prev_pos, pos - prev_pos ));
//locations是一个pair vector,执行完此句locations就变成{(0, 0)......}了
   locations->push_back( make_pair( line_pos, word_pos ));

                        word_pos++; pos++; prev_pos = pos;
                }

         cout << "last word on line substring: "
                     << textline.substr( prev_pos, pos-prev_pos )
       << "/n";

                words->push_back( textline.substr( prev_pos, pos - prev_pos ));
  locations->push_back( make_pair( line_pos, word_pos ));
        }
 
        return new text_loc( words, locations ); //( Alice, (0, 0) ) ........
}


// text_loc是一个( vector<string>*, vector<pair(short,short) >) pair
// display_text_locations首先分离出words和locations,先判断两者的匹配情况
// 因为每对应一个word就应该有一个location,简言之,就是一个对一个,因为它们都是
// vector
void
display_text_locations( text_loc *text_locations )
{
        vector<string>   *text_words     = text_locations->first;
        vector<location> *text_locs      = text_locations->second;

        register int elem_cnt = text_words->size();

        if ( elem_cnt != text_locs->size() )
        {
      cerr << "oops! internal error: word and position vectors "
    << "are of unequal size/n"
    << "words: " << elem_cnt << " "
    << "locs: "  << text_locs->size()
    << " -- bailing out!/n";
      exit( -2 );
 }

        for ( int ix = 0; ix < elem_cnt; ix++ )
        {
  cout << "word: " << (*text_words)[ ix ] << "/t"
       << "location: ("
       << (*text_locs)[ix].first  << ","
       << (*text_locs)[ix].second << ")"
       << "/n";
 }

        cout << endl;
}


 main2.cpp

void
filter_text( vector<string> *words, string filter )
{
 vector<string>::iterator iter = words->begin();
 vector<string>::iterator iter_end = words->end();

        if ( ! filter.size() )
             filter.insert( 0, "/".," );

        cout << "filter elements: " << filter << endl;

 while ( iter != iter_end )
 {
  cout << "filter_text: " << *iter << endl;

                string::size_type pos = 0;
//find_first_of如果没有找到匹配的项会返回string::npos所以可以用string::npos做为标志
                while (( pos = (*iter).find_first_of( filter, pos )) != string::npos )
                {
                        cout << "found! : pos: "
        << pos << "/t"
        << (*iter)[pos] << endl;

   // this is wrong: erases from pos to npos
                        // (*iter).erase(pos);
                        (*iter).erase(pos,1);

   cout << "after: " << *iter << endl;
                }

  cout << "finished with word: " << *iter << endl;

  iter++;
 }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值