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

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>
              国产精品久久国产愉拍| 在线亚洲电影| 欧美好骚综合网| 久久精品国产精品亚洲精品| 亚洲欧美成人网| 欧美一区二区三区久久精品茉莉花| 亚洲蜜桃精久久久久久久| 亚洲欧洲精品一区二区三区 | 久久久久久久综合日本| 久久免费少妇高潮久久精品99| 久久免费视频在线观看| 嫩草成人www欧美| 欧美日韩在线观看视频| 国产视频一区在线| **性色生活片久久毛片| 亚洲美女福利视频网站| 午夜精彩视频在线观看不卡 | 欧美激情一区二区三区四区| 欧美精品尤物在线| 国产亚洲精品一区二区| 99pao成人国产永久免费视频| 亚洲欧美激情四射在线日| 久久久精品性| 亚洲区免费影片| 亚洲一级黄色片| 另类综合日韩欧美亚洲| 国产精品久久国产愉拍| 亚洲日本欧美日韩高观看| 午夜视频一区| 亚洲国产精品va在线观看黑人| 在线综合亚洲| 欧美国产免费| 国产一级揄自揄精品视频| 亚洲最黄网站| 欧美国产亚洲精品久久久8v| 亚洲欧美日韩国产精品| 欧美国产精品一区| 激情丁香综合| 午夜电影亚洲| 亚洲精品一区在线观看香蕉| 美女视频网站黄色亚洲| 国产无遮挡一区二区三区毛片日本| 亚洲人成免费| 你懂的网址国产 欧美| 亚洲欧美日韩成人| 欧美日韩免费一区二区三区| 国产精品豆花视频| 激情六月综合| 久久成人人人人精品欧| 欧美一区二区三区免费看 | 午夜一区在线| 欧美日韩精品免费观看视一区二区| 黄色成人在线观看| 欧美与黑人午夜性猛交久久久| 亚洲人成啪啪网站| 欧美 亚欧 日韩视频在线| 一色屋精品视频在线观看网站| 欧美在线视频导航| 亚洲桃色在线一区| 国产精品美女999| 亚洲午夜久久久久久久久电影院| 亚洲国产人成综合网站| 欧美a级片网站| 亚洲精品视频中文字幕| 亚洲第一狼人社区| 欧美xxxx在线观看| 亚洲深爱激情| 亚洲校园激情| 国内成人精品2018免费看| 久久久噜噜噜久久久| 久久精品亚洲精品| 亚洲高清不卡在线| 亚洲欧洲精品成人久久奇米网| 欧美日韩国产精品专区 | 国产亚洲精品v| 久久久美女艺术照精彩视频福利播放| 午夜精品视频在线观看一区二区| 国产中文一区二区三区| 久热精品视频在线观看| 老巨人导航500精品| 日韩视频二区| 亚洲综合视频一区| 狠狠色综合网| 亚洲二区在线视频| 欧美色大人视频| 久久久久久久久久久一区| 久久综合九色综合欧美就去吻| 亚洲国产视频一区二区| 亚洲免费电影在线观看| 国产日韩精品一区二区浪潮av| 久久亚洲电影| 欧美日韩一区二区三区四区在线观看 | 91久久中文字幕| 99视频精品全国免费| 国产精品自拍三区| 欧美1区2区3区| 国产精品美女999| 欧美不卡在线| 亚洲第一在线视频| 亚洲深夜福利网站| 国内精品久久久久久久影视麻豆 | 欧美美女bb生活片| 久久精品国产亚洲a| 美女网站久久| 欧美一区午夜精品| 欧美超级免费视 在线| 亚洲欧美一区二区在线观看| 久久亚洲私人国产精品va| 亚洲欧美精品在线观看| 免费在线观看一区二区| 欧美在线91| 欧美伦理91| 欧美不卡在线| 国产农村妇女毛片精品久久麻豆| 欧美国产精品va在线观看| 国产免费观看久久| 一区二区三区精品视频在线观看 | 亚洲大片av| 欧美在线观看网站| 一区二区三区日韩精品| 久久久水蜜桃| 久久精品国产亚洲aⅴ| 国产精品视频xxxx| 亚洲精选在线观看| 一区二区三区导航| 欧美激情亚洲精品| 亚洲高清一区二| 永久免费视频成人| 久久福利视频导航| 久久天天躁狠狠躁夜夜爽蜜月| 国产精品美女www爽爽爽| 日韩午夜在线| 亚洲欧美精品在线观看| 国产精品成人免费| 亚洲午夜一区二区三区| 一区二区国产在线观看| 欧美日韩国产综合视频在线观看| 91久久精品一区二区别| 91久久极品少妇xxxxⅹ软件| 免费不卡在线观看| 亚洲欧洲日夜超级视频| 日韩视频第一页| 欧美日韩一区二区三区免费看| 亚洲美女电影在线| 亚洲一区在线直播| 国产美女一区| 久久精品人人做人人综合| 美脚丝袜一区二区三区在线观看| **欧美日韩vr在线| 欧美成在线视频| 日韩亚洲综合在线| 亚洲欧美国产视频| 国产午夜精品一区理论片飘花 | 久久精品91| 亚洲福利视频免费观看| 亚洲欧洲日本专区| 欧美日韩视频免费播放| 亚洲精品国产精品国自产在线| 亚洲精品一线二线三线无人区| 在线不卡免费欧美| 欧美va亚洲va国产综合| 亚洲精品系列| 久久国产精品亚洲77777| 亚洲大胆美女视频| 欧美视频你懂的| 久久久精品一品道一区| 亚洲精品欧美在线| 久久久精彩视频| 日韩网站在线| 国产一区二区精品| 欧美日韩精品久久久| 久久精品72免费观看| 日韩一级在线观看| 久久午夜激情| 亚洲一区影院| 亚洲理伦在线| 国内久久精品视频| 欧美午夜不卡| 欧美aⅴ一区二区三区视频| 亚洲一区二区三区免费观看 | 在线亚洲精品福利网址导航| 国产精品综合久久久| 久久人人97超碰国产公开结果| 一本大道久久精品懂色aⅴ| 免费亚洲电影在线观看| 欧美一区二区精品在线| 亚洲视屏一区| 亚洲国内精品| 国产亚洲成精品久久| 欧美日韩福利| 麻豆亚洲精品| 久久精品日韩一区二区三区| 亚洲视频日本| 亚洲美女区一区| 美日韩在线观看| 蜜臀va亚洲va欧美va天堂 | 最近中文字幕mv在线一区二区三区四区 | 国产精品国产福利国产秒拍| 免费人成网站在线观看欧美高清 | 欧美日本在线视频|