accelerated C++ 中查找url(学习笔记)

这个程序用来查找被称为url(统一资源地)的万维网地址,输入一行包含url的字符串,程序会帮你识别并输出字符串里所包含的全部url。

url的格式: protocol-name(协议名称)://resource-name(资源名称)

在看这个程序之前,记录一下这一章接触的新的知识点:

1.isalnum(c)函数:

在#<cctype>中定义,如果c是一个字母或者数字则结果是true

其余类似的函数有:

isspace(c)  如果c是一个空白字符则结果为true      isalpha(c)如果c是一个字母字符则为true

isdigit(c)  如果是一个数字字符则为true                       ispunct(c如果是一个标点字符则结果为true

isupper(c)  如果是一个大写字母则结果为true             islower(c)如果c 是一个小写字母则为true

toupper(c)  产生一个等于c的大写字母                         tolower(c)产生一个等于c的小写字母

2.find_if函数

find_if(a,b,c)  包含3个参数,前两个参数表示查找范围,是迭代器类型,第三个参数是一个函数指针或者函数对象,它的的作用是在容器范围内,返回一个使第三个参数所指函数为真的元素的迭代器

find函数

  与find_if 有点类似,但和find_if不同,它不会调用第三个参数所给定的值,反而会去查找做给的第三个参数,如果找到,则返回第三个参数的迭代器,没找到,就返回第二个参数的迭代器。

search函数:

search(a,b,c,d) 第一队迭代器指示了一对我们要查找的的序列,第二对指示了一个序列——我们希望为这个序列定位

(三个都是在#include <algorithm>中)

下面先简单介绍程序中的几个函数:

vector<string>  find_urls(const string& s)          //通过用迭代器d查找“://”  以查找查找全部的url

string::const_iterator  url_beg(string::const_iterator b,string::const_iterator e)      //查找url的前面部分

string::const_iterator  url_end(string::const_iterator b,string::const_iterator e)     //查找url的后面部分

bool not_url_char(charc)            //如果传过来的字符不可能出现在url中,则返回true

下面是整个函数,外加一个main的测试函数:

#include<iostream>
#include<string>
#include<vector>
#include<cctype>    
#include<algorithm>
using namespace std;   
bool not_url_char(char c){
    //除去字母数字之外,其他可能出现的urlzifu
    static const string url_ch = "~;/:@=&_.+!'(),";        //static是静态变量,有全局寿命       
    return !(isalnum(c) ||
         find(url_ch.begin(),url_ch.end(),c)  !=url_ch.end());    //检查字符c是否有出现
    }  
string::const_iterator 
    url_beg(string::const_iterator b,string::const_iterator e){
    static const string sep = "://";
    typedef string::const_iterator iter;                           //简化字符串的迭代器
        iter i = b;                                              //i标记查找到的分隔符:
        while((i = search(i,e,sep.begin(),sep.end())) !=e) {
        
            if(i != b && i+sep.size() != e){    
                iter beg = i;                                    //beg标记协议的名称的头部
                while(beg!=b&&isalpha(beg[-1]))
                    --beg;              
              if(beg!=i && !not_url_char(i[sep.size()]))      //分隔符前后至少有一个字符
                    return beg;
            }            
            i+=sep.size();                                     //所找到的分隔符不是一个url的部分
        }
        return e;
    }
string::const_iterator                                        //url_end 函数
        url_end(string::const_iterator b,string::const_iterator e){
    
        return find_if(b,e,not_url_char);
    }
vector<string>  find_urls(const string& s){    
    vector<string>  ret;
    typedef string::const_iterator iter;
    iter b = s.begin(), e = s.end();    
    
    while(b!=e){                                   //检查整个输入                
        b = url_beg(b,e);                          //查找一个或多个紧跟着://d 字母

        if(b!=e){                                  //如果查找成功获取此url的其余部分            
            iter after = url_end(b,e);                     
            ret.push_back(string(b,after));       //记住这个url

                b = after;                        //向前推进
            }
        }
        return ret;
    }
int main(){                                      //用于测试的主函数
    string s;
    getline(cin,s);
    vector<string> v=find_urls(s);
    for(vector<string>::size_type i =0;i<v.size();++i)
        cout<<v[i]<<endl;
    return 0;
}      

 

posted @ 2013-08-08 17:12  兰幽  阅读(555)  评论(0编辑  收藏  举报