Linux C程式設計一些函式彙總
之前專案用到的函式彙總一下:
1.access
原型:int access(const char *filenpath, int mode);
標頭檔案:io.h
功 能: 確定檔案或資料夾的訪問許可權。檢查某個檔案的存取方式,比如說是隻讀方式、只寫方式等。如果指定的存取方式有效,則函式返回0,否則函式返回-1。
用 法:
int access(const char *filenpath, int mode);
或者int _access( const char *path, int mode );
引數說明:filenpath檔案或資料夾的路徑,
備註:當該引數為檔案的時候,access函式能使用mode引數所有的值,當該引數為資料夾的時候,access函式值能判斷資料夾是否存在。在WIN NT 中,所有的資料夾都有讀和寫許可權
mode要判斷的模式,在標頭檔案unistd.h中的預定義如下:
#define R_OK 4 /* Test for read permission. */
#define W_OK 2 /* Test for write permission. */
#define X_OK 1 /* Test for execute permission. */
#define F_OK 0 /* Test for existence. */
2.fopen
原型:fp=fopen("file a","r");
例如:
FILE *fp;
fp=fopen("file a","r");
其意義是在當前目錄下開啟檔案file a,只允許進行“讀”操作,並使fp指向該檔案。
又如:
FILE *fphzk
fphzk=fopen("c:\\hzk16","rb");
其意義是開啟C驅動器磁碟的根目錄下的檔案hzk16,這是一個二進位制檔案,只允許按二進位制方式進行讀操作。兩個反斜線“\\ ”中的第一個表示轉義字元,第二個表示根目錄。
1) 檔案使用方式由r,w,a,t,b,+六個字元拼成,各字元的含義是:
r(read): 只讀
w(write): 只寫
a(append): 追加
t(text): 文字檔案,可省略不寫
b(binary): 二進位制檔案
+: 讀和寫
2) 凡用“r”開啟一個檔案時,該檔案必須已經存在,且只能從該檔案讀出。
3) 用“w”開啟的檔案只能向該檔案寫入。若開啟的檔案不存在,則以指定的檔名建立該檔案,若開啟的檔案已經存在,則將該檔案刪去,重建一個新檔案。
4) 若要向一個已存在的檔案追加新的資訊,只能用“a”方式開啟檔案。如果指定檔案不存在則嘗試建立該檔案。
5) 在開啟一個檔案時,如果出錯,fopen將返回一個空指標值NULL。在程式中可以用這一資訊來判別是否完成開啟檔案的工作,並作相應的處理。因此常用以下程式段開啟檔案:
6) if((fp=fopen("c:\\hzk16","rb"))==NULL)
{
printf("\nerror on open c:\\hzk16 file!");
getch();
exit(1);
}
這段程式的意義是,如果返回的指標為空,表示不能開啟C盤根目錄下的hzk16檔案,則給出提示資訊“error on open c:\ hzk16 file!”,下一行getch()的功能是從鍵盤輸入一個字元,但不在螢幕上顯示。在這裡,該行的作用是等待,只有當用戶從鍵盤敲任一鍵時,程式才繼續執行,因此使用者可利用這個等待時間閱讀出錯提示。敲鍵後執行exit(1)退出程式。
7) 把一個文字檔案讀入記憶體時,要將ASCII碼轉換成二進位制碼,而把檔案以文字方式寫入磁碟時,也要把二進位制碼轉換成ASCII碼,因此文字檔案的讀寫要花費較多的轉換時間。對二進位制檔案的讀寫不存在這種轉換。
8) 標準輸入檔案(鍵盤),標準輸出檔案(顯示器),標準出錯輸出(出錯資訊)是由系統開啟的,可直接使用。
3. fgets
原型:char *fgets(char *buf, int bufsize, FILE *stream);
如果使用fgets()讀取某個檔案,第一次讀取的bufsize為5,而檔案的第一行有10個字元(算上'\n'),那麼讀取檔案的指標會偏移至當前讀取完的這個字元之後的位置。也就是第二次再用fgets()讀取檔案的時候,則會繼續讀取其後的字元。而,如果使用fgets() 讀取檔案的時候bufsize大於該行的字元總數加2(多出來的兩個,一個儲存檔案本身的'\n'換行,一個儲存字串本身的結束標識'\0'),檔案並不會繼續讀下去,僅僅只是這一行讀取完,隨後指向檔案的指標會自動偏移至下一行。
4.atoi
原型:int atoi(const char *nptr);
是把字串轉換成整型數的一個函式
1 2 3 4 5 6 7 8 9 10 11 12 |
//vs2013裡呼叫printf函式請使用預處理命令#define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <stdio.h>
int main(void) { int n; char *str = "12345.67"; n = atoi(str); printf("n=%d\n",n); return 0; } |
(1)
輸出:
n = 12345
(2)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//vs2013裡呼叫printf函式請使用預處理命令#define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <stdio.h>
int main() { char a[] = "-100"; char b[] = "123"; int c; c = atoi(a) + atoi(b); printf("c=%d\n", c); return 0; } |
執行結果:
c = 23
5.pthread_create
原型: int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,(void*)(*start_rtn)(void*),void *arg);
它的功能是建立執行緒(實際上就是確定呼叫該執行緒函式的入口點),線上程建立以後,就開始執行相關的執行緒函式。
第二個引數用來設定執行緒屬性。
第三個引數是執行緒執行函式的起始地址。
最後一個引數是執行函式的引數。
標頭檔案
|
#include<pthread.h> |
pthread_create的返回值 表示成功,返回0;表示出錯,返回表示-1。
6. pthread_cond_timedwait
原型:int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
無論哪種等待方式,都必須和一個互斥鎖配合,以防止多個執行緒同時請求pthread_cond_wait()(或pthread_cond_timedwait(),下同)的競爭條件(Race Condition)。mutex互斥鎖必須是普通鎖(PTHREAD_MUTEX_TIMED_NP)或者適應鎖(PTHREAD_MUTEX_ADAPTIVE_NP),且在呼叫pthread_cond_wait()前必須由本執行緒加鎖(pthread_mutex_lock()),而在更新條件等待佇列以前,mutex保持鎖定狀態,並在執行緒掛起進入等待前解鎖。在條件滿足從而離開pthread_cond_wait()之前,mutex將被重新加鎖,以與進入pthread_cond_wait()前的加鎖動作對應。阻塞時處於解鎖狀態。
[參考]
1. https://www.cnblogs.com/qingxia/archive/2012/08/30/2663791.html
1. https://blog.csdn.net/whz_zb/article/details/6937673
7. pthread_mutex_lock
原型:int pthread_mutex_lock(pthread_mutex_t *mutex);
標頭檔案:#include <pthread.h>
對於靜態分配的互斥量, 可以把它設定為PTHREAD_MUTEX_INITIALIZER, 或者呼叫pthread_mutex_init.
對於動態分配的互斥量, 在申請記憶體(malloc)之後, 通過pthread_mutex_init進行初始化, 並且在釋放記憶體(free)前需要呼叫pthread_mutex_destroy.
2. 互斥操作:
對共享資源的訪問, 要對互斥量進行加鎖, 如果互斥量已經上了鎖, 呼叫執行緒會阻塞, 直到互斥量被解鎖. 在完成了對共享資源的訪問後, 要對互斥量進行解鎖。
首先說一下加鎖函式:
標頭檔案:
原型:
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
返回值: 成功則返回0, 出錯則返回錯誤編號.
[參考] https://blog.csdn.net/tennysonsky/article/details/46494077
8. fd_set
select()機制中提供一fd_set的資料結構,實際上是一long型別的陣列,每一個數組元素都能與一開啟的檔案控制代碼(不管是socket控制代碼,還是其他檔案或命名管道或裝置控制代碼)建立聯絡,建立聯絡的工作由程式設計師完成,當呼叫select()時,由核心根據IO狀態修改fd_set的內容,由此來通知執行了select()的程序哪一socket或檔案發生了可讀或可寫事件。
常見用法:
fd_set set;
FD_ZERO(&set); /*將set清零使集合中不含任何fd*/
FD_SET(fd, &set); /*將fd加入set集合*/
FD_CLR(fd, &set); /*將fd從set集合中清除*/
FD_ISSET(fd, &set); /*在呼叫select()函式後,用FD_ISSET來檢測fd是否在set集合中,當檢測到fd在set中則返回真,否則,返回假(0)*/
9.mkfifo
原型:int mkfifo(const char * pathname,mode_t mode);
標頭檔案:#include<sys/types.h>
mkfifo ()會依引數pathname建立特殊的FIFO檔案,該檔案必須不存在。
10. open
作用:開啟和建立檔案。
#include<fcntl.h>
int open(constchar*pathname,intflags);
int open(constchar*pathname,intflags,mode_tmode);
返回值:成功則返回檔案描述符,否則返回-1
O_RDONLY只讀模式
O_WRONLY只寫模式
O_RDWR讀寫模式
11.unlink
unlink 會刪除檔名,並減少連線數。如果是最後一個連線並且沒有程序開啟檔案,檔案將會被刪除,並釋放空間。如果是最後一個連線但是有程序開啟檔案,檔案仍會存在,直到開啟的檔案被關閉。
remove比unlink多了個刪除目錄的功能,在刪除檔案時,remove和unlink的功能是一樣的。
12. sem_init
原型:int sem_init(sem_t *sem, int pshared, unsigned int value);
如果 pshared 的值為 0,那麼訊號量將被程序內的執行緒共享;如果 pshared 是非零值,那麼訊號量將在程序之間共享。
sem_init() 成功時返回 0;錯誤時,返回 -1,並把 errno 設定為合適的值。
第一個引數:訊號量名 ;
第三個引數value表示可用的資源的數目。
[參考] https://blog.csdn.net/tomstrong_369/article/details/54312909
13. fcntl
通過fcntl可以改變已開啟的檔案性質。
O_NONBLOCK 如果pathname指的是一個FIFO檔案、塊裝置檔案或字元裝置檔案,則此選項將檔案的本次開啟操作和後續的I/O操作設定為非阻塞模式
14.pipe
每個程序各自有不同的使用者地址空間,任何一個程序的全域性變數在另一個程序中都看不到,所以程序之間要交換資料必須通過核心,在核心中開闢一塊緩衝區,程序A把資料從使用者空間拷到核心緩衝區,程序B再從核心緩衝區把資料讀走,核心提供的這種機制稱為程序間通訊。
#include <unistd.h>
int pipe (int fd[2]);
//返回:成功返回0,出錯返回-1
fd引數返回兩個檔案描述符,fd[0]指向管道的讀端,fd[1]指向管道的寫端。fd[1]的輸出是fd[0]的輸入。
[參考]1. https://blog.csdn.net/skyroben/article/details/71513385
匿名管道(pipe)
只能是具有血緣關係的程序之間通訊
命名管道(FIFO)
提供了一個路徑名與之關聯,以FIFO檔案的形式儲存於檔案系統中,能夠實現任何兩個程序之間通訊。而匿名管道對於檔案系統是不可見的,它僅限於在父子程序之間的通訊。
2. https://blog.csdn.net/qq_33951180/article/details/68959819
15. sem_post
原型:int sem_post(sem_t *sem);
標頭檔案:#include <semaphore.h>
sem_post是給訊號量的值加上一個“1”,它是一個“原子操作”---即同時對同一個訊號量做加“1”操作的兩個執行緒是不會衝突的;而同 時對同一個檔案進行讀和寫操作的兩個程式就有可能會引起衝突。
[參考]1.https://blog.csdn.net/fern_girl/article/details/61197995
2.https://blog.csdn.net/tietao/article/details/7367827
16. usleep
usleep()函式的功能是把呼叫該函式的執行緒掛起一段時間 [1] , 單位是微秒(microseconds:即百萬分之一秒); 標頭檔案: unistd.h 語法: void usleep(int micro_seconds); 返回值: 無 內容說明:本函式可暫時使程式停止執行。
17. pthread_join(pthread_detach)
在任何一個時間點上,執行緒是可結合的(joinable)或者是分離的(detached)。一個可結合的執行緒能夠被其他執行緒收回其資源和殺死。在被其他執行緒回收之前,它的儲存器資源(例如棧)是不釋放的。相反,一個分離的執行緒是不能被其他執行緒回收或殺死的,它的儲存器資源在它終止時由系統自動釋放
[參考] https://blog.csdn.net/u014774781/article/details/48039441
18. readdir
讀取目錄函式
標頭檔案:#include <sys/types.h> #include <dirent.h>
定義函式:struct dirent * readdir(DIR * dir);
[參考] http://c.biancheng.net/cpp/html/320.html
19.stat
標頭檔案: #include <sys/stat.h>
#include <unistd.h>
定義函式: int stat(const char *file_name, struct stat *buf);
函式說明: 通過檔名filename獲取檔案資訊,並儲存在buf所指的結構體stat中
返回值: 執行成功則返回0,失敗返回-1,錯誤程式碼存於errno
[參考] https://www.cnblogs.com/sylar5/p/6491033.html
20.S_ISDIR()函式
功能是判斷一個路徑是否為目錄
struct stat sb;
if(stat(fpath, &sb) >= 0 && S_ISDIR(sb.st_mode) && depth == 1)
{
// trave_dir(file->d_name, depth + 1);
continue;
}
21. select()
select(),本函式用於確定一個或多個套介面的狀態,對每一個套介面,呼叫者可查詢它的可讀性、可寫性及錯誤狀態資訊,用fd_set結構來表示一組等待檢查的套介面,在呼叫返回時,這個結構存有滿足一定條件的套介面組的子集,並且select()返回滿足條件的套介面的數目。有一組巨集可用於對fd_set的操作,這些巨集與Berkeley Unix軟體中的相容,但內部的表達是完全不同的。
#include <sys/select.h>
int select( int nfds, fd_set FAR* readfds, fd_set * writefds, fd_set * exceptfds, const struct timeval * timeout);
nfds:是一個整數值,是指集合中所有檔案描述符的範圍,即所有檔案描述符的最大值加1,不能錯!在 Windows中這個引數的值無所謂,可以設定不正確。
readfds:(可選)指標,指向一組等待可讀性檢查的套介面。
writefds:(可選)指標,指向一組等待可寫性檢查的套介面。
exceptfds:(可選)指標,指向一組等待錯誤檢查的套介面。
timeout:select()最多等待時間,對阻塞操作則為NULL。
返回值:
select()呼叫返回處於就緒狀態並且已經包含在fd_set結構中的描述字總數;如果超時則返回0;否則的話,返回SOCKET_ERROR錯誤,應用程式可通過WSAGetLastError獲取相應錯誤程式碼。
當返回為-1時,所有描述符集清0。
當返回為0時,表示超時。
當返回為正數時,表示已經準備好的描述符數。
select()返回後,在3個描述符集裡,依舊是1的位就是準備好的描述符。這也就是為什麼,每次用select後都要用FD_ISSET的原因。
22. recvfrom
一般情況下:
send(),recv()用於TCP,sendto()及recvfrom()用於UDP
但是send(),recv()也可以用於UDP,sendto()及recvfrom()也可以用於TCP