這是很基礎的教程,我只是寫給自己看,作為一個學習筆記記錄一下,如果正在閱讀的你覺得簡單,請不要批評,可以關掉選擇離開
如何學好一門編程語言
- 掌握基礎知識,為將來進一步學習打下良好的基礎。
- 上機實踐,通過大量的例題學習怎么設計算法,培養解題思路。
- 養成良好的編碼習慣,注釋一定要寫,要不然保你一周后自己寫的代碼都不認識了。
在Windows中的頭文件為:#include <sys/types.h>
在Linux中的頭文件為:#include <dirent.h>
opendir():打開目錄函數
DIR * opendir(const char * name);
打開 name 指定的目錄,並返回DIR*形態的目錄流,和open()類似,接下來對目錄的讀取和搜索都要使用此返回值。
返回值:成功則返回DIR* 型態的目錄流,打開失敗則返回NULL。
錯誤代碼:
- EACCESS 權限不足
- EMFILE 已達到進程可同時打開的文件數上限
- ENFILE 已達到系統可同時打開的文件數上限
- ENOTDIR 參數name 非真正的目錄
- ENOENT 參數name 指定的目錄不存在, 或是參數name 為一空字符串
- ENOMEM 核心內存不足
做一個有高修養的程序員,當我們打開文件夾時,最好做一下判斷,是否打開成功
DIR *dir; // 目錄流 dir = opendir("../folder"); if (dir==NULL){ printf("!Error: Cant't open dir.\n"); exit(1); }
readdir():讀取目錄
struct dirent * readdir(DIR * dir);
讀取成功 返回 目錄流dir 的下個目錄進入點。有錯誤發生或讀取到目錄文件尾則返回NULL。
結構dirent 定義如下:
struct dirent { ino_t d_ino; //d_ino 此目錄進入點的inode ff_t d_off; //d_off 目錄文件開頭至此目錄進入點的位移 signed short int d_reclen; //d_reclen _name 的長度, 不包含NULL 字符 unsigned char d_type; //d_type d_name 所指的文件類型 d_name 文件名 har d_name[256]; };
案例:讀取Q_and_A文件夾的文件
#include <stdio.h> #include <dirent.h> int main() { DIR *dir; // 目錄流 struct dirent *ptr; dir = opendir("../R_and_A"); while ((ptr = readdir(dir)) != NULL) { printf("d_name : %s\n", ptr->d_name); } closedir(dir); } //d_name : . //d_name : .. //d_name : addr_to_digit.c //d_name : fen_and_he.c //d_name : read_license.c //d_name : struct_read_demo.c //d_name : struct_write_demo.c //d_name : test.txt
closedir():關閉目錄流
int closedir(DIR *dir);
rewinddir():重設讀取目錄的位置為開頭位置
void rewinddir(DIR *dir);
案例

#include <stdio.h> #include <dirent.h> int main() { DIR *dir; struct dirent *ptr; dir = opendir("../Q_and_A"); while ((ptr = readdir(dir)) != NULL) { printf("d_name : %s\n", ptr->d_name); } rewinddir(dir); printf("readdir again!\n"); while ((ptr = readdir(dir)) != NULL) { printf("d_name : %s\n", ptr->d_name); } closedir(dir); }
seekdir():設置下回讀取目錄的位置
telldir():獲取目錄流的當前 讀取的 位置
void seekdir(DIR * dir, off_t offset);
案例

#include <stdio.h> #include <dirent.h> int main() { DIR *dir; struct dirent *ptr; int offset, offset_5, i = 0; dir = opendir("../R_and_A"); while ((ptr = readdir(dir)) != NULL) { offset = telldir(dir); // 獲取目錄流的讀取位置 if (++i == 5) offset_5 = offset; printf("d_name : %s offset :%d \n", ptr->d_name, offset); } seekdir(dir, offset_5); // 設置讀取目錄流的位置 printf("Readdir again!\n"); while ((ptr = readdir(dir)) != NULL) { offset = telldir(dir); // 獲取目錄流的讀取位置 printf("d_name : %s offset :%d\n", ptr->d_name, offset); } closedir(dir); }
getcwd():取得當前的工作目錄
char * getcwd(char * buf, size_t size);
將當前的工作目錄絕對路徑復制到參數buf 所指的內存空間,參數size 為buf 的空間大小。
返回值:執行成功則將結果復制到參數buf 所指的內存空間,或是返回自動配置的字符串指針;失敗返回NULL,錯誤代碼存於errno。
注:
- 在調用此函數時,buf 所指的內存空間要足夠大。若工作目錄絕對路徑的字符串長度超過參數size 大小,則返回NULL,errno 的值則為ERANGE。
- 倘若參數buf 為NULL,getcwd()會依參數size 的大小自動配置內存(使用malloc()),如果參數size 也為0,則getcwd()會依工作目錄絕對路徑的字符串程度來決定所配置的內存大小,進程可以在使用完次字符串后利用free()來釋放此空間。
#include <stdio.h> #include <unistd.h> void main() { char buf[80]; getcwd(buf, sizeof(buf)); printf("當前工作目錄為: %s\n", buf); // 當前工作目錄為: /mnt/c/Users/anker/Desktop/C_learn/cmake-build-debug }
fchdir():改變當前工作目錄
int fchdir(int fd);
將當前的工作目錄改變成以參數fd 所指的文件描述詞。
返回值:執行成功則返回 0,失敗返回-1,errno 為錯誤代碼。
#include <stdio.h> #include <fcntl.h> #include <unistd.h> int main() { int fd; fd = open("/tmp", O_RDONLY); fchdir(fd); printf("當前工作目錄為: %s \n", getcwd(NULL, NULL)); // 當前工作目錄為: /tmp close(fd); }
案例
讀取文件夾下所有的文件
/* * Author: 凌逆戰 | Never * Data: 2021/10/22 * Description: 讀取文件夾下所有的文件 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dirent.h> int readFileList(char *basePath, FILE *f) { DIR *dir; // 目錄流 struct dirent *ptr; // 目錄結構體指針 char base[1000]={0}; dir = opendir(basePath); // 打開目錄 if (dir== NULL) { perror("Open dir error..."); exit(1); } // 讀取目錄 while ((ptr = readdir(dir)) != NULL) { if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) // 當前目錄或父目錄 continue; else if (ptr->d_type == 8) { // file printf("d_name:%s/%s\n", basePath, ptr->d_name); fprintf(f, "%s/%s\n", basePath, ptr->d_name); } else if (ptr->d_type == 10){ // link file printf("d_name:%s/%s\n", basePath, ptr->d_name); } else if (ptr->d_type == 4) { // dir strcpy(base, basePath); strcat(base, "/"); strcat(base, ptr->d_name); readFileList(base, f); } } closedir(dir); return 1; } int main(void) { char absolute_path[1000]={0}; FILE *f; f = fopen("../wavlist.txt", "w"); strcpy(absolute_path, "../folder_wav"); readFileList(absolute_path, f); fclose(f); return 0; }
參考
【C語言中文網】C語言文件權限控制函數