日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

c语言 自动测试,C语言测试。自己实现scandir 函数

發(fā)布時(shí)間:2024/10/8 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言 自动测试,C语言测试。自己实现scandir 函数 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在C語(yǔ)言課程的后端,講完指針和標(biāo)準(zhǔn)文件IO處理,我會(huì)做出一個(gè)難度較大練習(xí),題目就是,利用標(biāo)準(zhǔn)的目錄處理函數(shù) opendir/readdir/closedir實(shí)現(xiàn)類似于 scandir的功能。其中接口要scandir 函數(shù)一致。

這個(gè)題目看起來簡(jiǎn)單,實(shí)現(xiàn)難度相當(dāng)大,主要采用復(fù)雜指針的操作。我第一次拿出來測(cè)試,全班大約只一二名實(shí)現(xiàn)80%的功能,其余很多覺得無從下手。程序很容易就會(huì)出現(xiàn)段錯(cuò)誤。基本上短時(shí)間內(nèi)正確的做出來的人可以劃歸專業(yè)級(jí)的程度了。有興趣的人可以先不看后面內(nèi)容,自行實(shí)現(xiàn)一下。

首先看一下man的scandir 接口定義

int scandir(const char *dir, struct dirent ***namelist,

int(*filter)(const struct dirent *),

int(*compar)(const struct dirent **, const struct dirent **));,從定義來看就不是一個(gè)簡(jiǎn)單的函數(shù),形參里,出現(xiàn)一個(gè)三級(jí)指針,二個(gè)函數(shù)指針。它的功能是,掃描名字為dir的目錄,把滿足filter函數(shù)的過濾條件(即filter執(zhí)行為非0值)的目錄項(xiàng)加入到一維指針數(shù)組namelist.數(shù)組的總長(zhǎng)度為返回值n,如果compar不為空,則最終輸出結(jié)果還要調(diào)用qsort來對(duì)數(shù)組進(jìn)行排序后再輸出。

從scandir的演示代碼,我們可以推算出namelist是一個(gè)指向一維指針數(shù)組的指針。(一維指針數(shù)組等同于 struct dirent ** namelist,這里寫在三級(jí)指針是因?yàn)橐獜暮瘮?shù)里改變namelist的值,必須再多做一級(jí))原因可以參考我的函數(shù)傳值類型的說明。

以下是一個(gè)簡(jiǎn)單掃描 /usr/lib,并且把所有以lib打頭的文件掃描到namelist數(shù)組的測(cè)試程序,這是參考scandir 提供的樣例來修改,alphasort是做原始的ASCII碼值比較進(jìn)行排序的

可以看到namelist是完全動(dòng)態(tài)分配的,不僅數(shù)組本身是動(dòng)態(tài)分配,而且數(shù)組項(xiàng)指向的空間也是動(dòng)態(tài)分配的。

#include

#include

#include

#include

#include

#include

#include

#include

//掃描所有的lib打頭的文件

int filter_fn(const struct dirent * ent)

{

if(ent->d_type != DT_REG)

return 0;

return (strncmp(ent->d_name,"lib",3) == 0);

}

void scan_lib(char * dir_name)

{

int n;

struct dirent **namelist; // struct dirent * namelist[];

n = scandir(dir_name, &namelist, filter_fn, alphasort);

if (n < 0)

perror("scandir");

else {

while(n--) {

printf("%s\n", namelist[n]->d_name);

free(namelist[n]);

}

free(namelist);

}

}

int main(int argc ,char * argv[])

{

scan_lib("/usr/lib");

}

從這個(gè)樣例,我們可以推算出namelist 的數(shù)據(jù)結(jié)構(gòu)是.另外一個(gè)難點(diǎn)是,這個(gè)數(shù)組是動(dòng)態(tài)形成的。即根據(jù)掃描結(jié)果來生成數(shù)組。這樣在函數(shù)里構(gòu)造這樣數(shù)據(jù)結(jié)構(gòu)還是相當(dāng)有難度。

最后正式程序如下。完全的源碼及測(cè)試程序參見附件。

/*

* Author : Andrew Huang *

*/

#define MAX_DIR_ENT 1024

typedef int(*qsort_compar)(const void *, const void *);

int hxy_scandir(const char *dir, struct dirent ***namelist,

int(*filter)(const struct dirent *),

int(*compar)(const struct dirent **, const struct dirent **))

{

DIR * od;

int n = 0;

struct dirent ** list = NULL;

struct dirent * ent ,* p;

if((dir == NULL) || (namelist == NULL))

return -1;

od = opendir(dir);

if(od == NULL)

return -1;

/* 分配一個(gè)最大數(shù)組 */

list = (struct dirent **)malloc(MAX_DIR_ENT*sizeof(struct dirent *));

while(( ent = readdir(od)) != NULL)

{

if( filter&& !filter(ent))

continue;

p = (struct dirent *)malloc(sizeof(struct dirent));

memcpy((void *)p,(void *)ent,sizeof(struct dirent));

list[n] = p;

n++;

if(n >= MAX_DIR_ENT)

break;

}

closedir(od);

/* 改變返回?cái)?shù)組大小*/

*namelist = realloc((void *)list,n*sizeof(struct dirent *));

if(*namelist == NULL)

*namelist = list;

/* 數(shù)組排序*/

if(compar)

qsort((void *)*namelist,n,sizeof(struct dirent *),(qsort_compar)compar);

return n;

}

文件:

hxy_scandir.zip

大小:

1KB

下載:

程序分析

1.這一個(gè)程序的第一個(gè)難點(diǎn)是 namelist個(gè)數(shù)不確定的.是根據(jù)掃描目錄的結(jié)果來確定,并且通過返回值告訴調(diào)用者.一種辦法是做兩次循環(huán),先掃描一次readdir從頭讀一次,確定個(gè)數(shù),然后再重新讀一次讀入內(nèi)容,這樣結(jié)果是準(zhǔn)確了,但是效率極低.另外一種方法讀入時(shí)采用是使用鏈表緩存,然后最后一次性存入數(shù)組.這樣代碼過于復(fù)雜了.

最后采用一個(gè)折中的辦法,即開始一次性分配最大值(1024)的數(shù)組,在讀入時(shí)直接對(duì)數(shù)組操作.這樣代碼處理簡(jiǎn)單,絕大部分情況能正確運(yùn)行.萬一有超過1024,一種是簡(jiǎn)單丟棄多余,二是擴(kuò)大最大值.這個(gè)方法是在效率和正確性采用一個(gè)折衷。

2.最后輸出時(shí),可以用realloc調(diào)整namelist大小再輸出,這樣可以節(jié)約堆空間。

3.關(guān)于最后的數(shù)組的排序,scandir文檔明確告之是采用qsort進(jìn)行排序,因此最后需要進(jìn)行這一步,關(guān)鍵是參數(shù)怎么填寫。

4.這個(gè)函數(shù)內(nèi)部的指針操作相當(dāng)復(fù)雜,象三級(jí)指針namelist最好不要直接使用,而是要在函數(shù)用一個(gè)中間指針變量struct dirent ** list來簡(jiǎn)化。而且在函數(shù)是直接將其作為數(shù)組

總結(jié)

以上是生活随笔為你收集整理的c语言 自动测试,C语言测试。自己实现scandir 函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美日韩tv| 小香蕉影院 | 一节黄色片 | 国产区在线看 | 国产123区| 男女视频在线免费观看 | 五月婷婷七月丁香 | 美女18网站 | 国产三级一区二区 | 日韩天堂视频 | 色婷婷av一区二区三区在线观看 | 中国女人内谢69xxxx | 成人av一区二区三区 | 欧美福利视频在线观看 | 日韩精品无 | 国产成人精品无码片区在线 | 国产日韩网站 | 又粗又大又硬毛片免费看 | 日日日噜噜噜 | 国产精品波多野结衣 | 日韩一区二区高清视频 | 欧美黑吊大战白妞欧美大片 | 三级全黄的视频 | 福利网站在线 | 午夜www| 日日干夜夜爽 | 成年人黄色一级片 | 韩国女主播一区二区 | 国产精品19乱码一区二区三区 | 国产乱码精品一区二区三区忘忧草 | 亚洲图片综合区 | 精品丰满少妇一区二区三区 | 亚洲aaa视频 | 欧美成人一区二免费视频软件 | 国产新婚疯狂做爰视频 | 欧产日产国产精品98 | 天堂新版8中文在线8 | 青青草精品 | 国精产品一二三区精华液 | 中国免费一级片 | 国产又粗又长视频 | 日韩性插| 欧美在线影院 | 在线观看第一页 | 国产在线第一页 | 久久手机免费视频 | 靠逼网站在线观看 | 一区二区三区视频在线观看免费 | 欧美成人精品欧美一级私黄 | 日本大奶少妇 | 日本精品久久久久久久 | 香蕉国产| 精品一区二区三区无码视频 | 日韩一区二区高清 | 深爱婷婷 | 中文字幕亚洲欧美日韩在线不卡 | 国产精品久久毛片av大全日韩 | 免看一级片 | 日韩极品视频在线观看 | 天天爽天天做 | 爱逼综合网| 日韩网红少妇无码视频香港 | 日韩av免费看 | 铠甲勇士猎铠 | 亚洲视频精品在线观看 | av在线免费播放网站 | 国产一区二区高清视频 | 国产91丝袜 | 亚洲国产日韩一区无码精品久久久 | 久久噜噜色综合一区二区 | 我想看一级黄色片 | 国产欧美一区二区三区国产幕精品 | 99re最新网址| 91国内揄拍国内精品对白 | 夫妻黄色片 | 国产福利一区二区三区视频 | 日本一区二区在线视频 | 在线亚洲精品 | 亚洲中文字幕视频一区 | 男人添女人下部高潮全视频 | 国产区视频在线 | 国产农村妇女毛片精品久久 | 四虎永久地址 | 欧美 日韩 高清 | 亚洲欧美日本另类 | 性www| 卡通动漫精品一区二区三区 | 国产欧美一区二区三区另类精品 | 在线视频这里只有精品 | 四虎精品欧美一区二区免费 | 99免费在线 | 天天射天天舔 | 日本一本视频 | 风韵少妇spa私密视频 | 一本一道av | 色婷婷狠 | 强开小受嫩苞第一次免费视频 | 免费av观看网站 | 亚洲永久免费av |