?? linux.txt
字號:
Linux系統下的C語言開發都需要學些什么
2007-11-07 10:21作者:佚名出處:論壇整理責任編輯:方舟 一、工具的使用
1、學會使用vim/emacs,vim/emacs是linux下最常用的源碼編輯具,不光要學會用它們編輯源碼,還要學會用它們進行查找、定位、替換等。新手的話推薦使用vim,這也是我目前使用的文本編輯器。
2、學會makefile文件的編寫規則,并結合使用工具aclocal、autoconf和automake生成makefile文件。
3、掌握gcc和gdb的基本用法。掌握gcc的用法對于構建一個軟件包很有益處,當軟件包包含的文件比較多的時候,你還能用gcc把它手動編譯出來,你就會對軟件包中各個文件間的依賴關系有一個清晰的了解。
4、掌握svn/cvs的基本用法。這是linux,也是開源社區最常用的版本管理系統。可以去試著參加sourceforge上的一些開源項目。
二、linux/unix系統調用與標準C庫
系統調用應用軟件與操作系統的接口,其重要性自然不用說,一定要掌握。推薦學習資料為steven先生的UNIX環境高級編程(簡稱APUE)。
三、庫的學習
無論是在哪個平臺做軟件開發,對于庫的學習都很重要,linux下的開發庫很多,我主要介紹一下我常常用到的一些庫。
1、glib庫
glib 庫是gtk+和gnome的基礎庫,并具是跨平臺的,在linux、unix和windows下都可以用。glib庫對于linux平臺開發的影響就像 MFC對windows平臺開發的影響一樣,很多開源項目都大量的使用了glib庫,包括gimp、gnome、gaim、evolution和 linux下的集群軟件heartbeat.因為glib庫自帶有基本的數據結構實現,所以在學習glib庫的時候可以順便學習一下基本的數據結構(包括鏈表、樹、隊列和hash表)。
2、libxml庫
libxml是linux平臺下解析XML文件的一個基礎庫,現在很多實用軟件都用XML格式的配置文件,所以也有必要學習一下。
3、readline庫
readline 庫是bash shell用的庫,如果要開發命令行程序,那么使用readline庫可以減少很多工作量,比如bash里的命令行自動補全,在readline里就已經有實現,當然你也可以用自己的實現替代庫的行為。readline庫有很多網站介紹的,只要google一下readline就可以找到一堆了。
4、curses庫
curses 庫以前是vi程序的一部分,后來從vi里提取出來成為一個獨立的庫。curses庫對于編寫終端相關的程序特別有用,比如要在終端某一行某一列定位輸出,改變終端字體的顏色和終端模式。linux下的curses庫用的是GNU實現的ncurses(new curses的意思)。
5、gtk+和KDE庫
這兩個庫是開發GUI應用程序的基礎庫,現在linux下的大部份GUI程序都是基于這兩個庫開發的,對于它們 的學習也是很有必要的。
四、網絡的學習
網絡這個東西太寬了,推薦學習資料steven先生的UNIX網絡編程(簡稱UNP)和TCP/IP協議詳解,更進一步的話可以學習使用libnet編寫網絡程序。
在Linux平臺下對文件編程可以使用兩類函數:(1)Linux操作系統文件API;(2)C語言I/O庫函數。 前者依賴于Linux系統調用,后者實際上與操作系統是獨立的,因為在任何操作系統下,使用C語言I/O庫函數操作文件的方法都是相同的。本章將對這兩種方法進行實例講解。
2.Linux文件API
Linux的文件操作API涉及到創建、打開、讀寫和關閉文件。
創建
int creat(const char *filename, mode_t mode);
參數mode指定新建文件的存取權限,它同umask一起決定文件的最終權限(mode&umask),其中umask代表了文件在創建時需要去掉的一些存取權限。umask可通過系統調用umask()來改變:
int umask(int newmask);
該調用將umask設置為newmask,然后返回舊的umask,它只影響讀、寫和執行權限。
打開
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
open函數有兩個形式,其中pathname是我們要打開的文件名(包含路徑名稱,缺省是認為在當前路徑下面),flags可以去下面的一個值或者是幾個值的組合:
標志 含義
O_RDONLY 以只讀的方式打開文件
O_WRONLY 以只寫的方式打開文件
O_RDWR 以讀寫的方式打開文件
O_APPEND 以追加的方式打開文件
O_CREAT 創建一個文件
O_EXEC 如果使用了O_CREAT而且文件已經存在,就會發生一個錯誤
O_NOBLOCK 以非阻塞的方式打開一個文件
O_TRUNC 如果文件已經存在,則刪除文件的內容
O_RDONLY、O_WRONLY、O_RDWR三個標志只能使用任意的一個。
如果使用了O_CREATE標志,則使用的函數是int open(const char *pathname,int flags,mode_t mode); 這個時候我們還要指定mode標志,用來表示文件的訪問權限。mode可以是以下情況的組合:
標志 含義
S_IRUSR 用戶可以讀
S_IWUSR 用戶可以寫
S_IXUSR 用戶可以執行
S_IRWXU 用戶可以讀、寫、執行
S_IRGRP 組可以讀
S_IWGRP 組可以寫
S_IXGRP 組可以執行
S_IRWXG 組可以讀寫執行
S_IROTH 其他人可以讀
S_IWOTH 其他人可以寫
S_IXOTH 其他人可以執行
S_IRWXO 其他人可以讀、寫、執行
S_ISUID 設置用戶執行ID
S_ISGID 設置組的執行ID
除了可以通過上述宏進行“或”邏輯產生標志以外,我們也可以自己用數字來表示,Linux總共用5個數字來表示文件的各種權限:第一位表示設置用戶ID;第二位表示設置組ID;第三位表示用戶自己的權限位;第四位表示組的權限;最后一位表示其他人的權限。每個數字可以取1(執行權限)、2(寫權限)、4(讀權限)、0(無)或者是這些值的和。例如,要創建一個用戶可讀、可寫、可執行,但是組沒有權限,其他人可以讀、可以執行的文件,并設置用戶ID位。那么,我們應該使用的模式是1(設置用戶ID)、0(不設置組ID)、7(1+2+4,讀、寫、執行)、0(沒有權限)、5(1+4,讀、執行)即10705:
open("test", O_CREAT, 10705);
上述語句等價于:
open("test", O_CREAT, S_IRWXU | S_IROTH | S_IXOTH | S_ISUID );
如果文件打開成功,open函數會返回一個文件描述符,以后對該文件的所有操作就可以通過對這個文件描述符進行操作來實現。
讀寫
在文件打開以后,我們才可對文件進行讀寫了,Linux中提供文件讀寫的系統調用是read、write函數:
int read(int fd, const void *buf, size_t length);
int write(int fd, const void *buf, size_t length);
其中參數buf為指向緩沖區的指針,length為緩沖區的大小(以字節為單位)。函數read()實現從文件描述符fd所指定的文件中讀取length個字節到buf所指向的緩沖區中,返回值為實際讀取的字節數。函數write實現將把length個字節從buf指向的緩沖區中寫到文件描述符fd所指向的文件中,返回值為實際寫入的字節數。
以O_CREAT為標志的open實際上實現了文件創建的功能,因此,下面的函數等同creat()函數:
int open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
定位
對于隨機文件,我們可以隨機的指定位置讀寫,使用如下函數進行定位:
int lseek(int fd, offset_t offset, int whence);
lseek()將文件讀寫指針相對whence移動offset個字節。操作成功時,返回文件指針相對于文件頭的位置。參數whence可使用下述值:
SEEK_SET:相對文件開頭
SEEK_CUR:相對文件讀寫指針的當前位置
SEEK_END:相對文件末尾
offset可取負值,例如下述調用可將文件指針相對當前位置向前移動5個字節:
lseek(fd, -5, SEEK_CUR);
由于lseek函數的返回值為文件指針相對于文件頭的位置,因此下列調用的返回值就是文件的長度:
lseek(fd, 0, SEEK_END);
關閉
當我們操作完成以后,我們要關閉文件了,只要調用close就可以了,其中fd是我們要關閉的文件描述符:
int close(int fd);
例程:編寫一個程序,在當前目錄下創建用戶可讀寫文件“hello.txt”,在其中寫入“Hello, software weekly”,關閉該文件。再次打開該文件,讀取其中的內容并輸出在屏幕上。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#define LENGTH 100
main()
{
int fd, len;
char str[LENGTH];
fd = open("hello.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); /* 創建并打開文件 */
if (fd)
{
write(fd, "Hello, Software Weekly", strlen("Hello, software weekly")); /* 寫入 Hello, software weekly字符串 */
close(fd);
}
fd = open("hello.txt", O_RDWR);
len = read(fd, str, LENGTH); /* 讀取文件內容 */
str[len] = '\0';
printf("%s\n", str);
close(fd);
}
編譯并運行,執行結果如下圖:
3.C語言庫函數
C庫函數的文件操作實際上是獨立于具體的操作系統平臺的,不管是在DOS、Windows、Linux還是在VxWorks中都是這些函數:
創建和打開
FILE *fopen(const char *path, const char *mode);
fopen()實現打開指定文件filename,其中的mode為打開模式,C語言中支持的打開模式如下表:
標志 含義
r, rb 以只讀方式打開
w, wb 以只寫方式打開。如果文件不存在,則創建該文件,否則文件被截斷
a, ab 以追加方式打開。如果文件不存在,則創建該文件
r+, r+b, rb+ 以讀寫方式打開
w+, w+b, wh+ 以讀寫方式打開。如果文件不存在時,創建新文件,否則文件被截斷
a+, a+b, ab+ 以讀和追加方式打開。如果文件不存在,創建新文件
其中b用于區分二進制文件和文本文件,這一點在DOS、Windows系統中是有區分的,但Linux不區分二進制文件和文本文件。
讀寫
C庫函數支持以字符、字符串等為單位,支持按照某中格式進行文件的讀寫,這一組函數為:
int fgetc(FILE *stream);
int fputc(int c, FILE *stream);
char *fgets(char *s, int n, FILE *stream);
int fputs(const char *s, FILE *stream);
int fprintf(FILE *stream, const char *format, ...);
int fscanf (FILE *stream, const char *format, ...);
size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
size_t fwrite (const void *ptr, size_t size, size_t n, FILE *stream);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -