日韩性视频-久久久蜜桃-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ò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚州视频在线 | 天天摸夜夜添 | 亚洲精品国产精品乱码视色 | 国产区亚洲区 | 久草婷婷| 老男人av| 欧美日韩国产在线一区 | 日韩精品一区二区三区在线观看 | 欧美综合日韩 | 91在线精品一区二区 | 成人av入口 | 青青草成人影视 | 狠狠操五月天 | 肉嫁高柳在线 | 日本涩涩视频 | 成人网页 | 大学生三级中国dvd 日韩欧美一区二区区 | 国产一级片精品 | 日韩精品第一区 | 老头巨大又粗又长xxxxx | 欧美高清性 | 中文字幕在线官网 | 丰满少妇大力进入 | 欧美日韩tv | 香蕉久久夜色精品国产使用方法 | 久久久999国产精品 天堂av中文在线 | 午夜电影网一区 | 精品欧美一区二区三区久久久 | 强伦人妻一区二区三区 | 日韩大片免费观看视频播放 | 国产激情第一页 | 日韩精品乱码久久久久久 | 国产三级自拍视频 | 亚洲黄色av | 午夜视频在线观看国产 | 欧美成人视 | 无人码人妻一区二区三区免费 | 丰满白嫩尤物一区二区 | 奇米影视久久久 | 国产成人午夜 | 欧美成人高潮一二区在线看 | 爱操影院 | 免费视频色 | 日日操夜夜操狠狠操 | 精品人妻无码一区二区三 | 一区二区三区视频观看 | 国产sm在线观看 | 国产精品欧美综合 | 91秘密入口| 久久国产在线观看 | 激情宗合| 又爽又黄又无遮挡 | 无码少妇一级AV片在线观看 | 欧美videos另类精品 | 日韩爽片 | 日日夜夜天天 | 国产让女高潮的av毛片 | 99re99| 99热这里只有精品在线观看 | 一级片一区二区三区 | 96av在线视频 | 一区二区三区在线免费观看视频 | 午夜av电影在线观看 | 91在线播放国产 | 亚洲一区黄色 | 手机av电影在线 | 欧美日韩在线观看一区二区三区 | 日本美女全裸 | av在线男人天堂 | 调教女m荡骚贱淫故事 | 中文字幕无码av波多野吉衣 | 九九视频在线 | 亚洲欧美日韩国产一区二区 | 亚洲天堂2021av| 91视频.com| 天天干天天操天天干 | 国产精品无码中文 | 肉色超薄丝袜脚交一区二区 | 97avcc| 日本黄色片一级 | 国产91精品高潮白浆喷水 | 青草视频在线播放 | 爆操网站 | 91精品综合久久久久久五月天 | 岛国av片 | 成品人视频ww入口 | 欧美日本黄色 | 日韩乱码人妻无码系列中文字幕 | 女生喷液视频 | 国产伦理一区二区三区 | av观看国产| 日本午夜精品理论片a级app发布 | 日本精品免费一区二区三区 | 亚洲av无码一区二区三区网址 | 精品久久久视频 | 亚洲春色另类 | 亚洲一区第一页 | 亚洲综合99 | 欧美伦理片 |