目次
MySQL 之动态字符串处理
ホームページ バックエンド開発 PHPチュートリアル MySQL 動的文字列処理_PHP チュートリアル

MySQL 動的文字列処理_PHP チュートリアル

Jul 12, 2016 am 09:03 AM
android

MySQL 之动态字符串处理

MySQL中,常常会看到一些关于动态字符串的处理,列如:DYNAMIC_STRING。为了记录动态字符串的实际长度,缓冲区的最大长度,以及每次字符串需要调整时,及时分配新的内存,以及调整长度。MySQL使用了DYNAMIC_STRING来保存动态字符串相关的信息:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>typedef struct st_dynamic_string<br /> </li><li>{<br /></li><li>char *str;<br /></li><li>size_t length,max_length,alloc_increment;<br /></li><li>} DYNAMIC_STRING; </li></ol>
ログイン後にコピー
在这个结构体中,str存储实际字符串的首地址,length记录字符串的实际长度,max_length记录字符串缓冲区最多可以存放多少字符,alloc_increment表示当字符串需要分配内存时,每次分配多少内存。

下面看看这个结构体的初始化过程:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,size_t init_alloc, size_t alloc_increment)<br /> </li><li>{<br /></li><li>size_t length;<br /></li><li>DBUG_ENTER("init_dynamic_string");<br /></li><li><br /></li><li>if (!alloc_increment) <br /></li><li>alloc_increment=128;<br /></li><li>length=1;<br /></li><li>if (init_str && (length= strlen(init_str)+1) < init_alloc) <br /></li><li>init_alloc=((length+alloc_increment-1)/alloc_increment)*alloc_increment; <br /></li><li>if (!init_alloc)<br /></li><li>init_alloc=alloc_increment;<br /></li><li><br /></li><li>if (!(str->str=(char*) my_malloc(init_alloc,MYF(MY_WME))))<br /></li><li>DBUG_RETURN(TRUE);<br /></li><li>str->length=length-1;<br /></li><li>if (init_str)<br /></li><li>memcpy(str->str,init_str,length);<br /></li><li>str->max_length=init_alloc;<br /></li><li>str->alloc_increment=alloc_increment;<br /></li><li>DBUG_RETURN(FALSE);<br /></li><li>} </li></ol>
ログイン後にコピー
从上述函数可以看到,初始化时,初始分配的字符串缓冲区大小init_alloc会根据需要初始的字符串来做判断。在分配好该DYNAMIC_STRING空间之后,我们会根据缓冲区的大小,字符串的实际长度,以及alloc_increment来初始化:length:字符串的实际长度max_length:缓冲区的最大长度alloc_increment:空间不够时,下次分配内存的单元大小.

初始化这些内容之后,如果下次需要在该缓冲区添加更多字符,就可以根据这些值来判断是否需要对该缓冲区扩容:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,<br /> </li><li>size_t length)<br /></li><li>{<br /></li><li>char *new_ptr;<br /></li><li>if (str->length+length >= str->max_length) //如果新增字符串后,总长度超过缓冲区大小<br /></li><li>{<br /></li><li>//需要分配多少个alloc_increment 大小的内存,才能存下新增后的字符串<br /></li><li>size_t new_length=(str->length+length+str->alloc_increment)/<br /></li><li>str->alloc_increment; <br /></li><li>new_length*=str->alloc_increment;<br /></li><li><br /></li><li>if (!(new_ptr=(char*) my_realloc(str->str,new_length,MYF(MY_WME))))<br /></li><li>return TRUE;<br /></li><li>str->str=new_ptr;<br /></li><li>str->max_length=new_length;<br /></li><li>}<br /></li><li>//将新分配的内容,append到str之后<br /></li><li>memcpy(str->str + str->length,append,length);<br /></li><li>str->length+=length; //扩容之后str新的长度<br /></li><li>str->str[str->length]=0; /* Safety for C programs */ //字符串最后一个字符为’\0'<br /></li><li>return FALSE;<br /></li><li>} </li></ol>
ログイン後にコピー
从上述代码可以看到,在字符串初始化化好之后,之后如果需要给该字符串增加新的内容,只需要根据之前存储的信息来动态的realloc就好了。由于该结构体记录了字符串相关的完整内容,所以动态的扩容会非常方便处理。
当然,除了这些,还有比如字符串截断,字符串初始设置,转义OS的引号等等:将字符串偏移大于N之后的截断。

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>my_bool dynstr_trunc(DYNAMIC_STRING *str, size_t n)<br /> </li><li>{<br /></li><li>str->length-=n;<br /></li><li>str->str[str->length]= '\0';<br /></li><li>return FALSE;<br /></li><li>} </li></ol>
ログイン後にコピー
返回字符串中第一次出现某个字符的地址。若没有,则返回字符串结尾的地址(指向’\0')

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>char *strcend(register const char *s, register pchar c)<br /> </li><li>{<br /></li><li>for (;;)<br /></li><li>{<br /></li><li>if (*s == (char) c) return (char*) s;<br /></li><li>if (!*s++) return (char*) s-1;<br /></li><li>}<br /></li><li>} </li></ol>
ログイン後にコピー
字符串内容扩容:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>my_bool dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size)<br /> </li><li>{<br /></li><li>DBUG_ENTER("dynstr_realloc");<br /></li><li><br /></li><li>if (!additional_size) DBUG_RETURN(FALSE);<br /></li><li>if (str->length + additional_size > str->max_length) //如果新的字符串内容超过缓冲区的最大长度<br /></li><li>{<br /></li><li>str->max_length=((str->length + additional_size+str->alloc_increment-1)/<br /></li><li>str->alloc_increment)*str->alloc_increment;<br /></li><li>if (!(str->str=(char*) my_realloc(str->str,str->max_length,MYF(MY_WME))))<br /></li><li>DBUG_RETURN(TRUE);<br /></li><li>}<br /></li><li>DBUG_RETURN(FALSE);<br /></li><li>} </li></ol>
ログイン後にコピー
对字符串用引号括起来,对其中的单引号进行转义,主要用于执行一些系统命令(system(cmd))。比如:ls -al 会变成 \'ls -al\'比如:ls -a’l会变成\’ls -a\\\’l\'

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>/*<br /> </li><li>Concatenates any number of strings, escapes any OS quote in the result then<br /></li><li>surround the whole affair in another set of quotes which is finally appended<br /></li><li>to specified DYNAMIC_STRING. This function is especially useful when<br /></li><li>building strings to be executed with the system() function.<br /></li><li><br /></li><li>@param str Dynamic String which will have addtional strings appended.<br /></li><li>@param append String to be appended.<br /></li><li>@param ... Optional. Additional string(s) to be appended.<br /></li><li><br /></li><li>@note The final argument in the list must be NullS even if no additional<br /></li><li>options are passed.<br /></li><li><br /></li><li>@return True = Success.<br /></li><li>*/<br /></li><li><br /></li><li>my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append, ...)<br /></li><li>{<br /></li><li><br /></li><li>const char *quote_str= "\'";<br /></li><li>const uint quote_len= 1;<br /></li><li>my_bool ret= TRUE;<br /></li><li>va_list dirty_text;<br /></li><li><br /></li><li>ret&= dynstr_append_mem(str, quote_str, quote_len); /* Leading quote */<br /></li><li>va_start(dirty_text, append);<br /></li><li>while (append != NullS)<br /></li><li>{<br /></li><li>const char *cur_pos= append;<br /></li><li>const char *next_pos= cur_pos;<br /></li><li><br /></li><li>/* Search for quote in each string and replace with escaped quote */<br /></li><li>while(*(next_pos= strcend(cur_pos, quote_str[0])) != '\0')<br /></li><li>{<br /></li><li>ret&= dynstr_append_mem(str, cur_pos, (uint) (next_pos - cur_pos));<br /></li><li>ret&= dynstr_append_mem(str ,"\\", 1);<br /></li><li>ret&= dynstr_append_mem(str, quote_str, quote_len);<br /></li><li>cur_pos= next_pos + 1;<br /></li><li>}<br /></li><li>ret&= dynstr_append_mem(str, cur_pos, (uint) (next_pos - cur_pos));<br /></li><li>append= va_arg(dirty_text, char *);<br /></li><li>}<br /></li><li>va_end(dirty_text);<br /></li><li>ret&= dynstr_append_mem(str, quote_str, quote_len); /* Trailing quote */<br /></li><li><br /></li><li>return ret;<br /></li><li>} </li></ol>
ログイン後にコピー
通过定义动态字符串的结构体信息,每次分次进行字符串添加更多字符,都会根据字符串的当前的长度动态的扩容。而且每次扩容后,该结构体都记录的当前字符串的实际信息(当前字符串的长度,缓冲器可容纳字符串的长度,进行扩容的单元长度)。这样,动态字符串的处理操作就变得非常方便了。



www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1079090.htmlTechArticleMySQL 之动态字符串处理 MySQL中,常常会看到一些关于动态字符串的处理,列如:DYNAMIC_STRING。为了记录动态字符串的实际长度,缓冲区的最...
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

新しいレポートは、噂のSamsung Galaxy S25、Galaxy S25 Plus、Galaxy S25 Ultraのカメラアップグレードのひどい評価を提供します 新しいレポートは、噂のSamsung Galaxy S25、Galaxy S25 Plus、Galaxy S25 Ultraのカメラアップグレードのひどい評価を提供します Sep 12, 2024 pm 12:23 PM

ここ数日、Ice Universeは、サムスンの次期主力スマートフォンであると広く信じられているGalaxy S25 Ultraの詳細を着実に明らかにしている。とりわけ、リーカーはサムスンがカメラのアップグレードを1つだけ計画していると主張した

Samsung Galaxy S25 Ultraの最初のレンダリング画像がリークされ、噂のデザイン変更が明らかに Samsung Galaxy S25 Ultraの最初のレンダリング画像がリークされ、噂のデザイン変更が明らかに Sep 11, 2024 am 06:37 AM

OnLeaks は、X (旧 Twitter) のフォロワーから 4,000 ドル以上を集めようとして失敗した数日後、Android Headlines と提携して Galaxy S25 Ultra のファーストルックを提供しました。コンテキストとして、h の下に埋め込まれたレンダリング イメージ

IFA 2024 | TCLのNXTPAPER 14は、パフォーマンスではGalaxy Tab S10 Ultraに匹敵しませんが、サイズではほぼ匹敵します IFA 2024 | TCLのNXTPAPER 14は、パフォーマンスではGalaxy Tab S10 Ultraに匹敵しませんが、サイズではほぼ匹敵します Sep 07, 2024 am 06:35 AM

TCLは、2つの新しいスマートフォンの発表に加えて、NXTPAPER 14と呼ばれる新しいAndroidタブレットも発表しました。その巨大な画面サイズはセールスポイントの1つです。 NXTPAPER 14 は、TCL の代表的なブランドであるマット LCD パネルのバージョン 3.0 を搭載しています。

Vivo Y300 Pro は、7.69 mm のスリムなボディに 6,500 mAh のバッテリーを搭載 Vivo Y300 Pro は、7.69 mm のスリムなボディに 6,500 mAh のバッテリーを搭載 Sep 07, 2024 am 06:39 AM

Vivo Y300 Pro は完全に公開されたばかりで、大容量バッテリーを備えた最もスリムなミッドレンジ Android スマートフォンの 1 つです。正確に言うと、このスマートフォンの厚さはわずか 7.69 mm ですが、6,500 mAh のバッテリーを搭載しています。これは最近発売されたものと同じ容量です

Samsung Galaxy S24 FEは、4色と2つのメモリオプションで予想よりも低価格で発売されると請求されています Samsung Galaxy S24 FEは、4色と2つのメモリオプションで予想よりも低価格で発売されると請求されています Sep 12, 2024 pm 09:21 PM

サムスンは、ファンエディション(FE)スマートフォンシリーズをいつアップデートするかについて、まだ何のヒントも提供していない。現時点では、Galaxy S23 FE は 2023 年 10 月初めに発表された同社の最新版のままです。

新しいレポートは、噂のSamsung Galaxy S25、Galaxy S25 Plus、Galaxy S25 Ultraのカメラアップグレードのひどい評価を提供します 新しいレポートは、噂のSamsung Galaxy S25、Galaxy S25 Plus、Galaxy S25 Ultraのカメラアップグレードのひどい評価を提供します Sep 12, 2024 pm 12:22 PM

ここ数日、Ice Universeは、サムスンの次期主力スマートフォンであると広く信じられているGalaxy S25 Ultraの詳細を着実に明らかにしている。とりわけ、リーカーはサムスンがカメラのアップグレードを1つだけ計画していると主張した

Xiaomi Redmi Note 14 Pro Plusは、Light Hunter 800カメラを搭載した初のQualcomm Snapdragon 7s Gen 3スマートフォンとして登場します Xiaomi Redmi Note 14 Pro Plusは、Light Hunter 800カメラを搭載した初のQualcomm Snapdragon 7s Gen 3スマートフォンとして登場します Sep 27, 2024 am 06:23 AM

Redmi Note 14 Pro Plusは、昨年のRedmi Note 13 Pro Plus(Amazonで現在375ドル)の直接の後継者として正式に発表されました。予想通り、Redmi Note 14 Pro Plusは、Redmi Note 14およびRedmi Note 14 Proと並んでRedmi Note 14シリーズをリードします。李

iQOO Z9 Turbo Plus: 強化されたシリーズフラッグシップの予約開始 iQOO Z9 Turbo Plus: 強化されたシリーズフラッグシップの予約開始 Sep 10, 2024 am 06:45 AM

OnePlus の姉妹ブランドである iQOO の製品サイクルは 2023 年から 4 年で、ほぼ終わりに近づいている可能性があります。それにもかかわらず、ブランドはまだZ9シリーズの開発を終えていないと宣言しました。その最終、そしておそらく最高エンドとなる Turbo+ バリアントが、予測どおりに発表されました。 T

See all articles