1. 程式人生 > >《Linux程式設計》第三章(標準IO庫、格式化輸入輸出、檔案和目錄的維護、掃描目錄)

《Linux程式設計》第三章(標準IO庫、格式化輸入輸出、檔案和目錄的維護、掃描目錄)

標準IO庫

  • 在啟動程式時,有三個檔案流是自動開啟的,分別是stdin,stdout,stderr。
  • 1. fopen函式:用於檔案和終端的輸入和輸出。函式原型如下:
  • #include <stdio.h>
    FILE *fopen(const char* filename,const char *mode);
  • mode 有幾種形式。需要注意的是,filename和mode都必須是字串,用雙引號。
  • 2.fread函式從檔案流stream中讀取到ptr指向的緩衝區,size指定每個資料記錄的長度,計數器nitems給出要傳輸的記錄個數。
  • 函式原型是#include<stdio.h> size_t fread(void *ptr,size_t size,size_t nitems, FILE *stream);
  • 3.fwrite從指定的資料緩衝區中取出資料記錄,並把它們寫到輸出流中。函式原型是
  • #include <stdio.h> size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream);
  • 4.fclose函式關閉指定的流檔案。函式原型是:#include <stdio.h> int fclose(FILE* stream)
  • 5.fflush函式將流檔案中未寫出的資料立刻寫出。#include <stdio.h> int fflush(FILE *stream);
  • 6.fgetc、getc、getchar函式
  • 7.fputc、putc、putchar函式
  • 8.fgets和gets函式

格式化輸入輸出

  • 1.printf、fprintf和sprintf函式,它們能夠控制格式輸出
  • 2.scanf、fscanf和sscanf函式,它們控制格式輸入
  • 3.其他流函式stdin、stdout、stderr函式
  • 4.為了表明錯誤,許多stdio庫函式會返回一個超出範圍的值,比如空指標或者EOF常數。錯誤由外部變數errno指出。 #include <errno.h> extern int errno; 也可以通過檢查流的狀態來確定是否發生了錯誤,或者到達了檔案尾。 #include <stdio.h> int ferror(FILE *stream);//測試一個檔案流的錯誤表示 int feof(FILE *stream);//測試一個檔案流的尾標識 void clearerr(FILE* stream);//清除由stream指向的檔案流的檔案尾標識和錯誤標識
  • 5.檔案流和檔案描述符 每個檔案流和底層檔案描述符相關聯。#include <stdio.h> int fileno(FILE *stream) FILE *fdopen(int fildes,const char *mode)

檔案和目錄的維護

  • 1.chmod系統呼叫可以改變檔案或者目錄的訪問許可權。函式原型如下: #include <sys/stat.h> int chmod(const char *path,mode_t mode);mode可以或操作。
  • 2.chown系統呼叫,能夠改變檔案的屬主 #include <sys/types.h> #include <unistd.h> int chown(const char* path, uid_t owner, gid_t group);
  • 3.unlink、link、symlink的系統呼叫:
  • 4.mkdir和rmdir系統呼叫:用來建立和刪除目錄 #include <sys/types.h> #include <sys/stat.h> int mkdir(const char* path,mode_t mode)//建立目錄 #include <unistd.h> int rmdir(const char *path)//刪除目錄
  • 5.chdir系統呼叫和getcwd函式 #include <unistd.h> int chdir(const char* path);//瀏覽目錄 #include <unistd.h> char *getcwd(char *buf,size_t size);//確定自己的當前目錄

掃描目錄

  • 1.opendir函式開啟一個目錄並建立一個目錄流 #include <sys/types.h> #include <dirent.h> DIR *opendir(const char *name);//如果大概的檔案過多,opendir可能會失敗
  • 2.readdir函式:返回一個指標,該指標值相等結構裡儲存著目錄流dirp中下一個目錄項的有關資料。 #include <sys/types.h> #include <dirent.h> struct dirent *readdir(DIR *dirp);
  • 3.telldir函式返回值記錄著一個目錄流的當前位置 #include <sys/types.h> #include <dirent.h> long int telldir(DIR *dirp);
  • 4.seekdir函式設定目錄流dirp的目錄項指標 #include <sys/types.h> #include <dirent.h> void seekdir(DIR* drip,long int loc);
  • 5.closedir函式關閉一個目錄流並釋放與之有關的資源 #include <sys/types.h> #include <dirent.h> int closedir(DIR *dirp);

列印目錄的實驗:

#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>

void printdir(char *dir,int depth)//列印目錄
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
if((dp=opendir(dir))==NULL){
 fprintf(stderr,"cannot open directory:%s\n",dir);//如果沒有開啟目錄,返回;
return;
}
chdir(dir);//瀏覽目錄
while((entry=readdir(dp))!=NULL){/*目錄項不為空,readdir返回一個dirent結構。該結構包含i節點和檔名*/
 lstat(entry->d_name,&statbuf);
if(S_ISDIR(statbuf.st_mode)){//判斷是個目錄
 if(strcmp(".",entry->d_name)==0||strcmp("..",entry->d_name)==0){continue;}
 printf("%*s%s/\n",depth,"",entry->d_name);
 printdir(entry->d_name,depth+4);
}
else{printf("%*s%s\n",depth,"",entry->d_name);}
}
chdir("..");
closedir(dp);

}

int main()
{
 printf("Directory scan of /home:\n");
 printdir("/home",0);
 printf("done.\n");
exit (0);
}

將main函式改為以下的樣子能夠列印目錄:

int main(int argc,char* argv[])
{
 char *topdir=".";
 if(argc>=2){topdir=argv[1];}
 printf("Directory scan of %s\n",topdir);
 printdir(topdir,0);
 printf("done.\n");
exit (0);
}