青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

C++ Programmer's Cookbook

{C++ 基礎(chǔ)} {C++ 高級(jí)} {C#界面,C++核心算法} {設(shè)計(jì)模式} {C#基礎(chǔ)}

STL----string

今天看stl中的string得:

一  問(wèn)題:

舉例來(lái)說(shuō),如果文本格式是:用戶名 電話號(hào)碼,文件名name.txt

Tom 23245332
Jenny 22231231
Heny 22183942
Tom 23245332
...
現(xiàn)在我們需要對(duì)用戶名排序,且只輸出不同的姓名。
-------------------------------

如果使用C/C++ 就麻煩了,他需要做以下工作:

  1. 先打開(kāi)文件,檢測(cè)文件是否打開(kāi),如果失敗,則退出。
  2. 聲明一個(gè)足夠大得二維字符數(shù)組或者一個(gè)字符指針數(shù)組
  3. 讀入一行到字符空間
  4. 然后分析一行的結(jié)構(gòu),找到空格,存入字符數(shù)組中。
  5. 關(guān)閉文件
  6. 寫一個(gè)排序函數(shù),或者使用寫一個(gè)比較函數(shù),使用qsort排序
  7. 遍歷數(shù)組,比較是否有相同的,如果有,則要?jiǎng)h除,copy...
  8. 輸出信息

-------------------------------------
我們可以使用 fstream來(lái)代替麻煩的fopen fread fclose, 用vector 來(lái)代替數(shù)組。最重要的是用 string來(lái)代替char * 數(shù)組,使用sort排序算法來(lái)排序,用unique 函數(shù)來(lái)去重。聽(tīng)起來(lái)好像很不錯(cuò) smile 。看看下面代碼(例程1):

#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <fstream>
using namespace std;
int main(){
        ifstream in("name.txt");
        string strtmp;
        vector<string> vect;
        while(getline(in, strtmp, '\n'))
        vect.push_back(strtmp.substr(0, strtmp.find(' ')));
        sort(vect.begin(), vect.end());
        vector<string>::iterator it=unique(vect.begin(), vect.end());
        copy(vect.begin(), it, ostream_iterator<string>(cout, "\n"));
        return 0;
}
--------------------------------------------





string 函數(shù)列表
函數(shù)名 描述
begin 得到指向字符串開(kāi)頭的Iterator
end 得到指向字符串結(jié)尾的Iterator
rbegin 得到指向反向字符串開(kāi)頭的Iterator
rend 得到指向反向字符串結(jié)尾的Iterator
size 得到字符串的大小
length 和size函數(shù)功能相同
max_size 字符串可能的最大大小
capacity 在不重新分配內(nèi)存的情況下,字符串可能的大小
empty 判斷是否為空
operator[] 取第幾個(gè)元素,相當(dāng)于數(shù)組
c_str 取得C風(fēng)格的const char* 字符串
data 取得字符串內(nèi)容地址
operator= 賦值操作符
reserve 預(yù)留空間
swap 交換函數(shù)
insert 插入字符
append 追加字符
push_back 追加字符
operator+= += 操作符
erase 刪除字符串
clear 清空字符容器中所有內(nèi)容
resize 重新分配空間
assign 和賦值操作符一樣
replace 替代
copy 字符串到空間
find 查找
rfind 反向查找
find_first_of 查找包含子串中的任何字符,返回第一個(gè)位置
find_first_not_of 查找不包含子串中的任何字符,返回第一個(gè)位置
find_last_of 查找包含子串中的任何字符,返回最后一個(gè)位置
find_last_not_of 查找不包含子串中的任何字符,返回最后一個(gè)位置
substr 得到字串
compare 比較字符串
operator+ 字符串鏈接
operator== 判斷是否相等
operator!= 判斷是否不等于
operator< 判斷是否小于
operator>> 從輸入流中讀入字符串
operator<< 字符串寫入輸出流
getline 從輸入流中讀入一行


------------------------------------
三 string提供了三個(gè)函數(shù)滿足其要求:
const charT* c_str() const 
const charT* data() const 
size_type copy(charT* buf, size_type n, size_type pos = 0) const 
其中: 
  1. c_str 直接返回一個(gè)以\0結(jié)尾的字符串。
  2. data 直接以數(shù)組方式返回string的內(nèi)容,其大小為size()的返回值,結(jié)尾并沒(méi)有\(zhòng)0字符。
  3. copy 把string的內(nèi)容拷貝到buf空間中。

---------------------
四    basic_string 是基于字符序列容器(Sequence)的模板類, 包含了說(shuō)有序列容器的常用操作,同時(shí)也包含了字符串的標(biāo)準(zhǔn)操作,如"查找"和"合并" 。
typedef basic_string <char> string;
typedef basic_string<wchar_t> wstring;

五  Extended STL string

ext_string,提供一些常用的功能,例如:

  1. 定義分隔符。給定分隔符,把string分為幾個(gè)字段。
  2. 提供替換功能。例如,用winter, 替換字符串中的wende
  3. 大小寫處理。例如,忽略大小寫比較,轉(zhuǎn)換等
  4. 整形轉(zhuǎn)換。例如把"123"字符串轉(zhuǎn)換為123數(shù)字。

附錄:ext_string:


/**
 * @mainpage Extended STL string
 * @author Keenan Tims - ktims@gotroot.ca
 * @version 0.2
 * @date 2005-04-17
 * @section desc Description
 * ext_string aims to provide a portable, bug-free implementation of many useful extensions to the
 * standard STL string class.  These extensions are commonly available among higher-level languages
 * such as Perl and Python, but C++ programmers are generally left on their own when it comes to
 * basic string processing.  By extending the STL's string, we can provide a drop-in replacement for STL
 * strings with the greater functionality of higher-level languages.
 *
 * The primary goal of this library is to make the STL string class more usable to programmers that
 * are doing simple string manipulation on a small scale.  Due to the usability goals of this class,
 * many actions will be inefficiently implemented for the sake of ease of use.  Some of this is
 * mitigated somewhat by doing modification in-place, however many unnecessary copies of data are
 * created by some methods, and the vector-returning methods are inefficient in that they copy the
 * substrings into the vector, then return a copy of the vector.  This would be much more efficient
 * as an iterator model.
 *
 *
 * @section feat Features
 *
 * @li Fully based on the STL, ext_string provides a superset of std::string methods
 * @li String splitting (tokenizing), on a character, a string, or whitespace
 * @li Replacement of substrings or characters with another string or character
 * @li String case operations (check, adjust)
 * @li Integer conversion
 * @li Fully open-source under a BSD-like license for use in any product
 *
 * @if web
 * @section download Downloads
 *
 * Downloads are provided in tar.gz and zip formats containing this documentation, the header file,
 * and the library's changelog.  The latest version of ext_string is 0.2, released on April 17,
 * 2005.
 *
 * @li<a href="files/ext_string-0.2.tar.gz">ext_string-0.2.tar.gz</a>
 * @li<a href="files/ext_string-0.2.zip">ext_string-0.2.zip</a>
 * @li <small><a href="files/ext_string-0.1.tar.gz">ext_string-0.1.tar.gz</a></small>
 * @li <small><a href="files/ext_string-0.1.zip">ext_string-0.1.zip</a></small>
 *
 * @section changelog Changelog
 *
 * The changelog is viewable online <a href="files/CHANGELOG">here</a>
 *
 * @endif
 *
 * @section notes Notes/Limitations
 * @li Copying all the substrings into a vector for the substring methods is pretty inefficient,
 * both for space and time.  It would be more prudent to model an iterator to split the string based
 * on the specified parameters, but this is more difficult to implement and more cumbersome to use.
 * Performance is not the main goal of this library, usability is, thus the tradeoff is deemed to be
 * acceptable.
 * @li References are not used too aptly in this class.  Some performance tuning could be done to
 * minimize unnecessary data copying.
 * @li The basic methods of std::string aren't overridden by this class, thus assigning the return
 * value of eg. string::insert() to an ext_string instance will make an unnecessary string object
 * which is then copy-constructed to an ext_string (I believe, internal workings of inheritance and
 * polymorphism in C++ are somewhat beyond my experience).  These methods should be wrapped by
 * ext_string to return the proper type.
 *
 *
 * @section related Related Documentation
 *
 * @li SGI's STL string reference: http://www.sgi.com/tech/stl/basic_string.html
 *
 *
 * @section license License
 *
 * Copyright (c) 2005, Keenan Tims
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
 * @li Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 * @li Redistributions in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or other materials provided with
 * the distribution.
 * @li Neither the name of the Extended STL String project nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 */

#ifndef _EXT_STRING_H
#define _EXT_STRING_H

#include <string>
#include <vector>

namespace std
{

 /**
  * An extension of STL's string providing additional functionality that is often availiable in
  * higher-level languages such as Python.
  */
 class ext_string : public string
 {
  public:
   /**
    * Default constructor
    *
    * Constructs an empty ext_string ("")
    */
   ext_string() : string() { }

   /**
    * Duplicate the STL string copy constructor
    *
    * @param[in] s   The string to copy
    * @param[in] pos The starting position in the string to copy from
    * @param[in] n   The number of characters to copy
    */
   ext_string(const string &s, size_type pos = 0, size_type n = npos) : string(s, pos, npos) { }

   /**
    * Construct an ext_string from a null-terminated character array
    *
    * @param[in] s The character array to copy into the new string
    */
   ext_string(const value_type *s) : string(s) { }

   /**
    * Construct an ext_string from a character array and a length
    *
    * @param[in] s The character array to copy into the new string
    * @param[in] n The number of characters to copy
    */
   ext_string(const value_type *s, size_type n) : string(s, n) { }

   /**
    * Create an ext_string with @p n copies of @p c
    *
    * @param[in] n The number of copies
    * @param[in] c The character to copy @p n times
    */
   ext_string(size_type n, value_type c) : string(n, c) { }

   /**
    * Create a string from a range
    *
    * @param[in] first The first element to copy in
    * @param[in] last  The last element to copy in
    */
   template <class InputIterator>
    ext_string(InputIterator first, InputIterator last) : string(first, last) { }

   /**
    * The destructor
    */
   ~ext_string() { }

   /**
    * Split a string by whitespace
    *
    * @return A vector of strings, each of which is a substring of the string
    */
   vector<ext_string> split(size_type limit = npos) const
   {
    vector<ext_string> v;

    const_iterator
     i = begin(),
       last = i;
    for (; i != end(); i++)
    {
     if (*i == ' ' || *i == '\n' || *i == '\t' || *i == '\r')
     {
      if (i + 1 != end() && (i[1] == ' ' || i[1] == '\n' || i[1] == '\t' || i[1] == '\r'))
       continue;
      v.push_back(ext_string(last, i));
      last = i + 1;
      if (v.size() >= limit - 1)
      {
       v.push_back(ext_string(last, end()));
       return v;
      }
     }
    }

    if (last != i)
     v.push_back(ext_string(last, i));

    return v;
   }

   /**
    * Split a string by a character
    *
    * Returns a vector of ext_strings, each of which is a substring of the string formed by splitting
    * it on boundaries formed by the character @p separator.  If @p limit is set, the returned vector
    * will contain a maximum of @p limit elements with the last element containing the rest of
    * the string.
    *
    * If @p separator is not found in the string, a single element will be returned in the vector
    * containing the entire string.
    *
    * The separators are removed from the output
    *
    * @param[in] separator The character separator to split the string on
    * @param[in] limit     The maximum number of output elements
    * @return A vector of strings, each of which is a substring of the string
    *
    * @section split_ex Example
    * @code
    * std::ext_string s("This|is|a|test.");
    * std::vector<std::ext_string> v = s.split('|');
    * std::copy(v.begin(), v.end(), std::ostream_iterator<std::ext_string>(std::cout, "\n"));
    *
    * This
    * is
    * a
    * test.
    * @endcode
    */
   vector<ext_string> split(value_type separator, size_type limit = npos) const
   {
    vector<ext_string> v;

    const_iterator
     i = begin(),
     last = i;
    for (; i != end(); i++)
    {
     if (*i == separator)
     {
      v.push_back(ext_string(last, i));
      last = i + 1;
      if (v.size() >= limit - 1)
      {
       v.push_back(ext_string(last, end()));
       return v;
      }
     }
    }

    if (last != i)
     v.push_back(ext_string(last, i));

    return v;
   }

   /**
    * Split a string by another string
    *
    * Returns a vector of ext_strings, each of which is a substring of the string formed by
    * splitting it on boundaries formed by the string @p separator.  If @p limit is set, the
    * returned vector will contain a maximum of @p limit elements with the last element
    * containing the rest of the string.
    *
    * If @p separator is not found in the string, a single element will be returned in the
    * vector containing the entire string.
    *
    * The separators are removed from the output
    *
    * @param[in] separator The string separator to split the string on
    * @param[in] limit     The maximum number of output elements
    * @return A vector of strings, each of which is a substring of the string
    *
    * @ref split_ex
    */
   vector<ext_string> split(const string &separator, size_type limit = npos) const
   {
    vector<ext_string> v;

    const_iterator
     i = begin(),
     last = i;
    for (; i != end(); i++)
    {
     if (string(i, i + separator.length()) == separator)
     {
      v.push_back(ext_string(last, i));
      last = i + separator.length();

      if (v.size() >= limit - 1)
      {
       v.push_back(ext_string(last, end()));
       return v;
      }
     }
    }

    if (last != i)
     v.push_back(ext_string(last, i));

    return v;
   }

   /**
    * Convert a string into an integer
    *
    * Convert the initial portion of a string into a signed integer.  Once a non-numeric
    * character is reached, the remainder of @p string is ignored and the integer that was
    * read returned.
    *
    * @param s The string to convert
    * @return The integer converted from @p string
    */
   static long int integer(const string &s)
   {
    long int retval = 0;
    bool neg = false;

    for (const_iterator i = s.begin(); i != s.end(); i++)
    {
     if (i == s.begin())
     {
      if (*i == '-')
      {
       neg = true;
       continue;
      }
      else if (*i == '+')
       continue;
     }
     if (*i >= '0' && *i <= '9')
     {
      retval *= 10;
      retval += *i - '0';
     }
     else
      break;
    }

    if (neg)
     retval *= -1;

    return retval;
   }

   /**
    * Convert the string to an integer
    *
    * Convert the initial portion of the string into a signed integer.  Once a non-numeric
    * character is reached, the remainder of the string is ignored and the integer that had
    * been read thus far is returned.
    *
    * @return The integer converted from the string
    */
   long int integer() const
   {
    return integer(*this);
   }

   /**
    * Split a string into chunks of size @p chunklen.  Returns a vector of strings.
    *
    * Splits a string into chunks of the given size.  The final chunk may not fill its
    * entire allocated number of characters.
    *
    * @param[in] chunklen The number of characters per chunk
    * @return A vector of strings, each of length <= chunklen
    *
    * @section chunk_split-ex Example
    * @code
    * std::ext_string s("abcdefghijk");
    * std::vector<std::ext_string> v = s.chunk_split(3);
    * std::copy(v.begin(), v.end(), ostream_iterator<std::ext_string>(cout, " "));
    *
    * abc def ghi jk
    * @endcode
    */
   vector<ext_string> chunk_split(size_type chunklen) const
   {
    vector<ext_string> retval;
    retval.reserve(size() / chunklen + 1);

    size_type count = 0;
    const_iterator
     i = begin(),
     last = i;
    for (; i != end(); i++, count++)
    {
     if (count == chunklen)
     {
      count = 0;
      retval.push_back(ext_string(last, i));
      last = i;
     }
    }
    
    if (last != i)
     retval.push_back(ext_string(last, i));

    return retval;
   }

   /**
    * Join a sequence of strings by some glue to create a new string
    *
    * Glue is not added to the end of the string.
    *
    * @pre [first, last) is a valid range
    * @pre InputIterator is a model of STL's Input Iterator
    * @pre InputIterator must point to a string type (std::string, std::ext_string, char *)
    *
    * @param[in] glue  The glue to join strings with
    * @param[in] first The beginning of the range to join
    * @param[in] last  The end of the range to join
    * @return A string constructed of each element of the range connected together with @p glue
    *
    * @section join_ex Example
    * @code
    * std::vector<std::ext_string> v;
    * v.push_back("This");
    * v.push_back("is");
    * v.push_back("a");
    * v.push_back("test.");
    * std::cout << std::ext_string::join("|", v.begin(), v.end()) << std::endl;
    *
    * This|is|a|test.
    * @endcode
    */
   template <class InputIterator>
    static ext_string join(const string &glue, InputIterator first, InputIterator last)
    {
     ext_string retval;

     for (; first != last; first++)
     {
      retval.append(*first);
      retval.append(glue);
     }
     retval.erase(retval.length() - glue.length());

     return retval;
    }

   /**
    * Join a sequence of strings by some glue to create a new string
    *
    * @copydoc join
    * @ref join_ex
    */
   template <class InputIterator>
    static ext_string join(value_type glue, InputIterator first, InputIterator last)
    {
     ext_string retval;

     for (; first != last; first++)
     {
      retval.append(*first);
      retval.append(1, glue);
     }
     retval.erase(retval.length() - 1);

     return retval;
    }

   /**
    * Search for any instances of @p needle and replace them with @p s
    *
    * @param[in] needle The string to replace
    * @param[in] s      The replacement string
    * @return    *this
    * @post     All instances of @p needle in the string are replaced with @p s
    *
    * @section replace-ex Example
    * @code
    * std::ext_string s("This is a test.");
    * s.replace("is", "ere");
    * std::cout << s << std::endl;
    *
    * There ere a test.
    * @endcode
    */
   ext_string &replace(const string &needle, const string &s)
   {
    size_type
     lastpos = 0,
     thispos;

    while ((thispos = find(needle, lastpos)) != npos)
    {
     string::replace(thispos, needle.length(), s);
     lastpos = thispos + 1;
    }
    return *this;
   }

   /**
    * Search of any instances of @p needle and replace them with @p c
    *
    * @param[in] needle The character to replace
    * @param[in] c      The replacement character
    * @return           *this
    * @post             All instances of @p needle in the string are replaced with @p c
    *
    * @ref replace-ex
    */
   ext_string &replace(value_type needle, value_type c)
   {
    for (iterator i = begin(); i != end(); i++)
     if (*i == needle)
      *i = c;

    return *this;
   }

   /**
    * Repeat a string @p n times
    *
    * @param[in] n The number of times to repeat the string
    * @return ext_string containing @p n copies of the string
    *
    * @section repeat-ex Example
    * @code
    * std::ext_string s("123");
    * s = s * 3;
    * std::cout << s << std::endl;
    *
    * 123123123
    * @endcode
    */
   ext_string operator*(size_type n)
   {
    ext_string retval;
    for (size_type i = 0; i < n; i++)
     retval.append(*this);

    return retval;
   }

   /**
    * Convert the string to lowercase
    *
    * @return *this
    * @post The string is converted to lowercase
    */
   ext_string &tolower()
   {
    for (iterator i = begin(); i != end(); i++)
     if (*i >= 'A' && *i <= 'Z')
      *i = (*i) + ('a' - 'A');
    return *this;
   }

   /**
    * Convert the string to uppercase
    *
    * @return *this
    * @post The string is converted to uppercase
    */
   ext_string &toupper()
   {
    for (iterator i = begin(); i != end(); i++)
     if (*i >= 'a' && *i <= 'z')
      *i = (*i) - ('a' - 'A');
    return *this;
   }

   /**
    * Count the occurances of @p str in the string.
    *
    * @return The count of substrings @p str in the string
    */
   size_type count(const string &str) const
   {
    size_type
     count = 0,
     last = 0,
     cur = 0;

    while ((cur = find(str, last + 1)) != npos)
    {
     count++;
     last = cur;
    }

    return count;
   }

   /**
    * Determine if the string is alphanumeric
    *
    * @return true if the string contains only characters between a-z, A-Z and 0-9 and
    * contains at least one character, else false
    */
   bool is_alnum() const
   {
    if (length() == 0)
     return false;

    for (const_iterator i = begin(); i != end(); i++)
    {
     if (*i < 'A' || *i > 'Z')
      if (*i < '0' || *i > '9')
       if (*i < 'a' || *i > 'z')
        return false;
    }

    return true;
   }

   /**
    * Determine if the string is alphabetic only
    *
    * @return true of the string contains only characters between a-z and A-Z and contains at
    * least one character, else false
    */
   bool is_alpha() const
   {
    if (length() == 0)
     return false;

    for (const_iterator i = begin(); i != end(); i++)
     if (*i < 'A' || (*i > 'Z' && (*i < 'a' || *i > 'z')))
      return false;

    return true;
   }

   /**
    * Determine if the string is numeric only
    *
    * @return true if the string contains only characters between 0-9 and contains at least
    * one character, else false
    */
   bool is_numeric() const
   {
    if (length() == 0)
     return false;

    for (const_iterator i = begin(); i != end(); i++)
     if (*i < '0' || *i > '9')
      return false;

    return true;
   }

   /**
    * Determine if a string is all lower case
    *
    * @return true if there is at least one character, and all characters are lowercase
    * letters, else false
    */
   bool is_lower() const
   {
    if (length() == 0)
     return false;

    for (const_iterator i = begin(); i != end(); i++)
     if (*i < 'a' || *i < 'z')
      return false;

    return true;
   }

   /**
    * Determine if a string is all upper case
    *
    * @return true if there is at least one character, and all characters are uppercase
    * letters, else false
    */
   bool is_upper() const
   {
    if (length() == 0)
     return false;

    for (const_iterator i = begin(); i != end(); i++)
     if (*i < 'A' || *i > 'Z')
      return false;

    return true;
   }

   /**
    * Swap the case of a string
    *
    * @post Converts all uppercase to lowercase, and all lowercase to uppercase in the string
    * @return *this
    */
   ext_string &swapcase()
   {
    for (iterator i = begin(); i != end(); i++)
     if (*i >= 'A' && *i <= 'Z')
      *i += ('a' - 'A');
     else if (*i >= 'a' && *i <= 'z')
      *i -= ('a' - 'A');
    
    return *this;
   }
 };
}
#endif
也可以找到 http://www.gotroot.ca/ext_string/

posted on 2005-12-13 16:25 夢(mèng)在天涯 閱讀(5681) 評(píng)論(1)  編輯 收藏 引用 所屬分類: STL/Boost

評(píng)論

# re: STL----string 2009-09-16 11:21 egmkang.wang

std::string::data()
結(jié)尾不一定有'\0'吧.
c_str是肯定有.

我自己實(shí)踐的結(jié)果是,data()也會(huì)返回'\0'結(jié)尾的const char*.
如果data()不返回,那么程序可能就會(huì)有問(wèn)題.......  回復(fù)  更多評(píng)論   

公告

EMail:itech001#126.com

導(dǎo)航

統(tǒng)計(jì)

  • 隨筆 - 461
  • 文章 - 4
  • 評(píng)論 - 746
  • 引用 - 0

常用鏈接

隨筆分類

隨筆檔案

收藏夾

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

積分與排名

  • 積分 - 1811983
  • 排名 - 5

最新評(píng)論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
      <noscript id="pjuwb"></noscript>
            <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
              <dd id="pjuwb"></dd>
              <abbr id="pjuwb"></abbr>
              国产欧美日韩亚洲精品| 欧美诱惑福利视频| 欧美激情综合色| 亚洲欧洲在线免费| 亚洲精品你懂的| 欧美精品二区| 亚洲欧美视频| 久久av老司机精品网站导航| 悠悠资源网亚洲青| 亚洲乱码国产乱码精品精可以看| 欧美日一区二区三区在线观看国产免| 亚洲欧美精品| 久久亚洲综合色一区二区三区| 99ri日韩精品视频| 亚洲免费视频成人| 亚洲人妖在线| 欧美亚洲日本网站| 一本久久综合| 久久精品国产精品亚洲| 99精品热视频| 久久精品视频一| 亚洲一区二区日本| 久久综合色播五月| 亚洲欧美一级二级三级| 久久综合伊人77777麻豆| 亚洲伊人色欲综合网| 久久久女女女女999久久| 亚洲在线播放电影| 久久综合给合久久狠狠色| 亚洲直播在线一区| 农村妇女精品| 久久先锋资源| 国产精品夜夜嗨| 亚洲精品美女在线| 亚洲成色精品| 欧美一区二视频| 亚洲在线成人精品| 欧美激情a∨在线视频播放| 久久久精品性| 国产精品日韩久久久| 亚洲看片网站| 亚洲精品影院在线观看| 久久精品国产精品亚洲精品| 亚洲永久网站| 欧美天天在线| 亚洲毛片网站| 亚洲美女一区| 欧美激情综合亚洲一二区| 老妇喷水一区二区三区| 国产九区一区在线| 亚洲视频综合| 午夜精品99久久免费| 欧美日韩国产一级| 亚洲经典自拍| 亚洲激情午夜| 欧美高清在线| 亚洲国产激情| 亚洲伦理在线| 欧美精品国产精品| 亚洲九九九在线观看| 日韩香蕉视频| 欧美日韩精品在线视频| 亚洲电影一级黄| 欧美大片免费观看| 影音先锋久久久| 久久久久久网站| 亚洲第一精品影视| 亚洲韩国青草视频| 欧美激情成人在线| 日韩亚洲欧美精品| 午夜精品久久久久久久白皮肤 | 欧美一区二区三区播放老司机| 亚洲免费在线| 国产日本欧洲亚洲| 久久成人国产精品| 免费在线国产精品| 日韩视频免费在线观看| 欧美日韩国产影片| 亚洲一区二区不卡免费| 久久国产欧美日韩精品| 亚洲成色最大综合在线| 欧美精品一区二区三区在线播放 | 亚洲欧美日韩一区二区| 久久久精品一区| 亚洲国产第一| 欧美日韩一区二区欧美激情| 亚洲自拍16p| 欧美第一黄色网| 亚洲欧美激情在线视频| 精品成人在线| 欧美日韩国产免费| 午夜精品婷婷| 91久久黄色| 欧美一区二区在线免费观看| 亚洲电影自拍| 国产精品xnxxcom| 久久久久久久国产| 一本色道久久综合亚洲精品婷婷 | 欧美一区二区大片| 91久久精品国产91久久| 欧美一区二区三区喷汁尤物| 在线电影国产精品| 国产精品magnet| 免费成人高清在线视频| 亚洲自拍另类| 亚洲精品欧美一区二区三区| 久久精彩免费视频| 一区二区免费在线播放| 在线不卡欧美| 国产午夜精品福利| 欧美日韩中文在线| 免费看亚洲片| 久久大香伊蕉在人线观看热2| 亚洲卡通欧美制服中文| 欧美国产第一页| 久久精品国产综合| 亚洲欧美日韩精品久久久| 亚洲黄色一区| 狠狠色综合一区二区| 国产精品欧美激情| 欧美日韩亚洲天堂| 欧美国产视频在线观看| 久久婷婷国产综合精品青草| 亚洲网站在线看| 夜夜嗨av一区二区三区免费区| 狼狼综合久久久久综合网| 久久综合中文字幕| 久久精品二区| 亚洲一区二区在线| 一本久久综合亚洲鲁鲁| 亚洲黄色视屏| 亚洲激情二区| 亚洲国产精品va在线观看黑人| 麻豆精品在线观看| 乱人伦精品视频在线观看| 久久精品成人一区二区三区| 午夜一区二区三区在线观看| 亚洲一区二区在线免费观看视频| 99精品福利视频| 一区二区免费在线视频| 99国产精品99久久久久久| 亚洲韩国青草视频| 亚洲精品久久7777| 亚洲精品日产精品乱码不卡| 亚洲人成7777| 亚洲美女精品成人在线视频| 99精品久久免费看蜜臀剧情介绍| 亚洲精品护士| 亚洲尤物精选| 久久精品人人做人人综合| 久久久水蜜桃av免费网站| 老色批av在线精品| 欧美高清视频一区| 亚洲精品一区二区在线| 亚洲天堂av电影| 欧美一区二区观看视频| 久久免费99精品久久久久久| 美女脱光内衣内裤视频久久影院| 老司机精品导航| 欧美日韩国产小视频在线观看| 欧美日韩综合不卡| 国产亚洲视频在线| 亚洲欧洲另类国产综合| 亚洲图中文字幕| 久久精品亚洲一区二区| 免播放器亚洲一区| 99精品国产高清一区二区| 亚洲欧美韩国| 欧美电影在线播放| 国产精品美女久久久久久2018| 国产日韩精品入口| 亚洲欧洲美洲综合色网| 亚洲欧美日韩国产精品| 男人的天堂成人在线| 亚洲免费不卡| 久久久久久久久蜜桃| 欧美精品尤物在线| 国产一区二区三区在线观看免费视频 | 奶水喷射视频一区| 欧美体内谢she精2性欧美| 国产一区999| 亚洲午夜久久久久久久久电影网| 久久国产手机看片| 日韩一区二区精品葵司在线| 欧美在线三级| 欧美视频一区在线观看| 尤物网精品视频| 亚洲欧美日本另类| 欧美激情女人20p| 欧美在线看片| 国产精品久久久久久久久久三级| 亚洲第一成人在线| 久久精品国产久精国产思思| 亚洲精品久久嫩草网站秘色 | 亚洲伦理网站| 久久久欧美一区二区| 国产精品捆绑调教| 一本久久青青| 亚洲日本在线观看| 免费不卡视频|