Giáo án - Bài giảng: CÁC NỘI DUNG CẦN ÔN TẬP VỚI C TRONG KHI HỌC C

44 585 0
Giáo án - Bài giảng: CÁC NỘI DUNG CẦN ÔN TẬP VỚI C TRONG KHI HỌC C

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Các nội dung cần ôn tập với c Kiến thức chung Kiến thức lập trình c trong UNIX về cơ bản cũng giống như học lập trình trong Borland c 3.1 ícòn gọi là phiên bản BC cho DOS) cho nên các bạn có thế tham khảo các cú pháp cũng như các hàm trong BC. Tuy nhiên chúng ta cũng cần nhấn mạnh 1 chút về các vấn đề sau: • Program Arguments. int main(int argc, char *argv[]) . o Chú ý rằng argv[0] luôn có và chính là tên chương trình, o Đế lấy các tham số và các đối số một cách đầy đủ thì cần dùng các hàm và biến môi trường như sau: #include <unistd.h> int getopt(int argc, char *const argv[], const char *optstring); extern char *optarg; extern int optind, opterr, optopt; • Environment Variables. Liệt kê hoặc thiết lập các biến môi trường thông qua các hàm và biến toàn cục như sau: extern char **environ; char *getenv(const char *name); int putenv(const char *string); Có 1 số bài tập như sau: 1. Giả sử có 1 chương trình cần chạy với 1 so options như -i, -1, -r, -f và sau -f sẽ có 1 argument. Khi đó chương trình chạy như sau: $ ./argopt -i -lr 'hi there' -f fred.c -q option: i option: 1 option: r option: f filename: fred.c argopt: invalid option— q unknown option: q argument: hi there Hãy viết chương trình minh họa để ra kết quả như trên. #include <stdio.h> iinclude <unistd.h> int main(int argc, char *argv[]) { int opt; while((opt = getopt(argc, argv, "if:lr")) != -1) { switch(opt) { case 'i': case '1' : case 'r': printf("option: %c\n", opt); break; 1/44 case 1f': printf("filename: %s\n", optarg); break; case ':': printf ("option needs a value\n"); break; case '? ' : printf("unknown option: %c\n", optopt); break; } for(; optind < argc; optind++) printf("argument: %s\n", argv[optind]); return (0); } 2. Hãy viêt chương trình làm việc với biên môi trường như sau: a. Liệt kê các biến môi trường của tiến trình hiện tại thông qua biến toàn cục environ. #include <stdlib.h> #include <stdio.h> int main() { char **env = environ; while(*env) { printf("%s\n",*env); env++; } return (0); } b. Lây thông tin của biên môi trường thông qua hàm getenv. Ví dụ như các biến PATH, HOME, ______________________________________ #include <stdlib.h> iinclude <stdio.h> #include <string.h> int main(int argc, char *argv[]) { char *var, *value; if (argc == 1 I I argc > 3) í fprintf (stderr,"usage: environ var [value]\n"); exit (1); > var = argv[1]; value = getenv(var); if(value) printf("Variable %s has value %s\n", var, value); else printf("Variable %s has no value\n", var); if(argc == 3) { char *string; value = argv[2]; 2/44 string = malloc(strlen(var)+strlen(value)+2); if(¡string) { fprintf(stderr,"out of memory\n"); exit (1); } strcpy(string,var); strcat(string,"="); strcat(string,value); printf("Calling putenv with: %s\n",string); if(putenv(string) != 0) { fprintf(stderr,"putenv failed\n"); free(string); exit (1); } value = getenv(var); if(value) printf("New value of %s is %s\n", var, value); else printf("New value of %s is null??\n", var); } return (0); Lam viec v<yi File Co hai ca che lam viec voi File. • Truy cap va thao tac vai File thong qua cac loi goi he thong. File Descriptor chuan: STDIN FILENO, STDOUT FILENO, va STDERR FILENO • Truy cap va thao tac voi File thong qua cac ham chuan thu vien. con tro chuan kieu FILE nhu: FILE * stdin, stdout, stderr. Cac ham lam viec cr muc thap - muc loi goi he thong truy cap den noi dung file: #include <unistd.h> int creat(const char *pathname, mode_t mode); int open(const char *pathname, int oflag, mode t mode); int close(int filedes); off_t seek(int filedes, off t offset, int whence); ssize_t read(int filedes, void *buf, size_t nbytes); ssize_t write(int filedes, const void *buf, size_t nbytes); int dup(int filedes); int dup2(int filedes, int filedes2); Cac ham truy cap den thuoc tinh cua file 3/44 #include <sys/stat.h> int stat(const char *restrict pathname, struct stat *restrict buf); int fstat(int filedes, struct stat *buf); struct stat { m odet stmode; /* file type & mode (permissions) */ ino_t st ino; /* i-node number (serial number) */ dev t st dev; /* device number (file system) */ dev_t st rdev; /* device number for special files */ nlink t st_nlink; /* number of links */ uid_t st uid; /* user ID of owner */ gid_t st gid; /* group ID of owner */ off t stsize; /* size in bytes, for regular files *1 time t st atime; /* time of last access */ time_t stjmtime; /* time of last modification */ time_t st_ctime; /* time of last file status change */ blksize t st blksize; /* best I/O block size */ blkcnt_t st blocks; /* number of disk blocks allocated */ }; Các hàm làm việc với thuộc tính của file : int access(const char *pathname, int mode); int chmod(const char *pathname, mode t mode); int fchmod(int filedes, mode t mode); int chown(const char *pathname, uid t owner, gid t group); int fchown(int filedes, uid_t owner, gid t group); int link(const char *existingpath, const char *newpath); int unlink(const char *pathname); int remove(const char *pathname); int rename(const char *oldname, const char *newname); int symlink(const char *actualpath, const char *sympath); ssizet readlink(const char* restrict pathname, char * restrict buf,size_t bufsize); Thư mục cũng là 1 kiểu File đặc biệt trong Unix. Đế truy cập thư mục Unix cung cấp các lời gọi hệ thống và cấu trúc như sau: 4/44 int mkdir(const char *pathname, mode_t mode); int rmdir(const char *pathname); struct dirent { ino_t d ino; /* i-node number */ char d_name[NAME_MAX + 1]; /* null-terminated filename */ } DIR *opendir(const char *pathname); struct dirent *readdir(DIR *dp); void rewinddir(DIR *dp); int closcdir(DIR *dp); long telldir(DIR *dp); void seekdir(DIR *dp, long loc); int chdir(const char *pathname); int fchdir(int filedes); char *getcwd(char *buf, size_t size); Các hàm làm việc với File trong thu viện chuấn: #include <stdio.h> FILE *fopen(const char *filename, const char *mode); sizet fread(void *ptr, size_t size, size_t nitems, FILE *stream); sizet fwrite (const void *ptr, size t size, size t nitems, FILE *stream); int fclose(FILE *stream); int fflush(FILE *stream); int fseek(FILE *stream, long int offset, int whence); int fgetc(FILE *stream); int getc(FILE *stream); int getchar(); int fputc(int c, FILE *stream); int putc(int c, FILE *stream); int putchar(int c); char *fgets(char *s, int n, FILE *stream); char *gets(char *s); int printf(const char *format, ); int sprintf(char *s, const char *format, ); int fprintf(FILE *stream, const char *format, ); int scanf(const char *format, ); int fscanf(FILE *stream, const char *format, ); int sscanf(const char *s, const char *format, ); int ferror(FILE *stream); int feof(FILE *stream); void clearerr(FILE *stream); int fileno(FILE *stream); FILE *fdopen(int tildes, const char *mode); 5/44 Với các hàm như vậy chúng ta có 1 số bài tập mẫu như sau: 3. Viết chương trình mô phỏng các lệnh cp, rm, mv trong Unix (sử dụng các lời gọi hệ thống hoặc các hàm thư viện). Lệnh copy: #include <stdio.h> #define MAX_LINE_LEN 1000 void main(int argc, char* argv[]) { char* file_path_from; /* source path */ char* file_path_to; /* target path */ FILE* f_from; /* source stream */ FILE* f_to; /* target stream */ char buf[MAX_LINE_LEN+1]; if (argc != 3 || !argv[l] || !argv[2]) { fprintf(stderr, "Usage: %s <source tile path> <target file path>\n",argv[0]); exit (1); } file_path_from = argv[l]; file_path_to = argv[2]; f_from = fopen(file_path_from, "r"); if (!f_from) { fprintf(stderr, "Cannot open source file: "); perror(""); exit (1); } f_to = fopen(file_path_to, "w+"); if (!f_from) { fprintf(stderr, "Cannot open target file: "); perror (""); exit (1); } while (fgets(buf, MAX_LINE_LEN+1, f_from)) { if (fputs(buf, f_to) == EOF) { fprintf(stderr, "Error writing to target file: perror(""); exit (1); } } if (!feof(f_from)) { fprintf(stderr, "Error reading from source file: "); perror(""); exit (1); } if (fclose(f_from) == EOF) { fprintf(stderr, "Error when closing source file: "); perror (""); } if (fclose(f_to) == EOF) { fprintf(stderr, "Error when closing target file: ") ; perror(""); } 6/44 4. Xác định thuộc tính của các file, mỏ phỏng công việc như khi chạy: $ Is -1 file name. #include <sỵs/stat.h> #include <stdio.h> #include <time.h> #include <io.h> #include <sys/types.h> #include <fcntl.h> int main(int argc, char * argv[]) { struct stat statbuf; int stream; char mode[20]="-rwxrwxrwx"; char output[200] char temp[20]=""; if (argc==l) { printf("Usage: %s <file_n return 1; } if ((stream = _open(argv[1', _0 { perror("Error:"); return 1; } fstat(stream, Sstatbuf); close(stream); II Kiem tra quyen if (!S_IRUSR(statbuf.st_mode) ) mode[1]='-'; if (!S_IWUSR(statbuf.st_mode) ) mode[ 2 ] ; if (!S_IXUSR(statbuf.st_mode) ) mode[3]='-' ; if (!S_IRGRP(statbuf.st_mode) ) mode[4]='-'; if (!S_IWGRP(statbuf.st_mode)) mode[ 5 ] =' -'; if (!S_IXGRP(statbuf.st_mode)) mode[6]='-'; if (!S_IROTH(statbuf.st_mode) ) mode[7]='-'; if (!S_IWOTH(statbuf.st_mode)) mode[8]='-'; if (!S_IXOTH(statbuf.st_mode)) mode[9]='-'; // kiem tra loai file if (S_ISLNK(statbuf.st_mode)) mode[0] = '1' ; else if (S_ISCHR(statbuf.st_node) ) mode[0]='c '; else if (S_ISBLK(statbuf.st_node)) mode[0]='b'; else if (S_ISSOCK(statbuf.stjnode)) mode[0]='s '; else if (S_ISFIFO(statbuf.st_mode)) mode[0]='p'; strcat(output,mode); sprintf(temp," %s ", ctime(Sstatbuf.st_ctime)); strcat(output,temp); strcat(output," "); strcat(output,argv[0]); return 0; 7/44 } 5. Mô phỏng chương trình thay đổi sở hữu hay quyền truy cập như: chmod, chown, chgrp. 6. Sử dụng các hàm dup, dup2 đế thay đối hướng vào ra dữ liệu. Ví dụ khi thực hiện hàm _____ printf thì kết quả không phái hiện ra màn hình mà ghi vào file nào đó._________________ #include <sỵs/stat.h> #include <fcntl.h> #include <unistd.h> int main(int argc, char **argv) { int fd = open(argv[1]/ 0_CREAT I 0_WR0NLY); //luu stdout int oldstdout = dup(l); //chuyen huong dup2(fd, 1); close(fd); //in ra file thaỵ vi stdout: printf("test"); //khoi phuc stdout dup2(oldstdout, 1); close(oldstdout); return 0; 2 ____________________ ______________ ______________________________________ _____________ 7. Chúng ta có 2 kiểu tạo file liên kêt (LINK). Hãy dùng các hàm liên quan để đọc nội dung _____ các file liên kết đỏ. Chú ý vói file liên kết mềm.___________________________________ #include <sỵs/stat.h> #include <fcntl.h> #include <unistd.h> #include <sỵs/types.h> #include <stdio.h> int main(int argc,char *argv']) { int fd = open(argv[1], 0_RD0NLY); struct stat statbuf; char buf[256]; fstat(fd, Sstatbuf); if (S_ISLNK(statbuf.st_mode) ) { // doc ten file chua trong file lien ket mem nay read(fd,buf,200); close(fd); fd = open(buf,0_RD0NLY); printf("\n %s is symbolic link to %s", argv[1],buf); } while (read(fd,buf,256)) printf("%s",buf); close(fd); return 0; 2_______________________________________________________________________________________ 8. Viet chương ừình đọc nội dung của thư mục, liệt kê các file và thư mục con của nó theo dạng cây thư mục với mức độ sâu cho trước. Ví dụ: nếu liệt kê thư mục TEMP với độ sâu là 2 thì ta liệt kê các file, thư mục trong thư mục TEMP và các file và thư mục trong các thư muc con của thư muc TEMP. #include <unistd.h> #include <stdio.h> #include <dirent.h> #include <strinq.h>__________________________________________________________ 8/44 #include <sys/stat.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) { stat(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); } #include <sys\stat.h> #include <fcntl.h> #include <unistd.h> #include <dirent.h> void printdir(char *dir,int aaxdepth) { static int depth = 0; Dir *dp; struct dirent *entry; struct stat statbuf; if ((dp= opendir(dir))==NULL) { perror("open:"); return; } chdir(dir); // tang do sau depth ++; while ((entry= readdir(dp))!=NULL) { stat(entry->d_name,Sstatbuf); ______ if (S ISDIR(statbuf.st mode)) 9/44 { if ( (strcmp (".",entrv->đ_name)==0) II strcmpC'. . ", entry->d_name) ==0) { continue; } printf ("%s/\n",entry->d_name); II neu dat do sau lon nhat thi dung de qui if (depth < maxdepth) { printdir(entry->d_name,maxdepth); } } else { // in ten file printf("\t%s",entry->d_name); } } closedir(dp); > int main(int argc,char *argv']) { if (argc < 3) { printf("\n Usage: %s <dir_name> <max_depth>",argvt0;); return 1; > int maxdepth = atoi(argv[2]); printdir(argv[1],maxdepth) ; printf("\n done! \n") ; return 0; } 9. Giả sử có 1 file với đường dần đầy đủ, hãy xác định quyền được đọc của file. Nếu file không có quyền được đọc đối với người dùng hiện tại, hãy xác định xem nguyên nhân bắt nguồn từ đâu (do thư mục cha,ông nào cuả nó không cho quyền đọc hay thực hiện). Cũng làm công việc như trên nhưng với đường dẫn bất kỳ, có thế là tuyệt đối ,có thế là tương đối. #include <stdio.h> finclude <unistd.h> finclude <string.h> #include <malloc.h> void main(int arge, char* argv[]) { char* file_path; char* dir_path; char* p_slash; if (arge != 2 || !argv[i;) { fprintf(stderr, "Usage: %s <full file path>\n", argv[0]); exit (1); } file_path = argv[l]; dir_path = (char*)malloc(strlen(file_path)+1); if (!dir_path) { _______ fprintf(stderr, "out of memory\n"); ______________________ 10/44 [...]... execl(const char *path, const char * a r g 0 , ( c h a r *)0); execlp(const char *file, const char * a r g 0 , ( c h a r *)0); execle(const char *path, const char * a r g 0 , ( c h a r *)0, const char *envp[]); execv(const char *path, const char *argvf]); execvp(const char *tile, const char *argv[]); execve(const char *path, const char *argv[], const char *envp[]); Với c c hàm này, chúng ta c 1 số bài. .. tien trinh cha printf("\n parent: %d %d %d %d %d %d", getpid 0 , getppid 0 , getuid 0 , geteuid 0 , getgid 0 , getegid 0); > return 0; } 12 Sử dụng hàm FORK đế tạo ra dãy c c tiên trình với quan hệ cha con như sau: a A -> B -> c -> D : t c là A là cha c a B, B là cha c a c, c là cha c a D b A -> (B, c, D ) : t c là A là cha c a B, c, D c Xây dựng c y chu trình... vi c sử dụng c c hàm sigaction và sigprocmask chúng ta xây dựng chương trình mô phỏng hàm sleep với tính năng như sau: Tiến trình gọi hàm Sleep sẽ bị tạm ngưng (block) cho đến khi một trong c c sự kiện sau xảy ra: a Thời gian đặt trong hàm Sleep kết th c b Một Signal kh c bị bắt bởi tiến trình và hàm th c hiện Signal handler trà lại kết quả (Bài này c tính minh họa đế c c bạn hiểu hơn về c ch sử dụng)... muc %s khong CO quyen thuc thi",parent); } else printf("\n Thu muc %s khong C O quyen doc",parent); return 0; } 10 Trong Unix, khi muốn th c hiện 1 file thì hệ thống sẽ x c định sự tôn tại c a file trư c Sự kiếm tra đó phụ thu c vào đường dẫn c a file C thế là đường dẫn tuyệt đối, tương đối ho c chỉ là 1 tên file c n chạy Trường hợp cuối thì hệ thống xẽ thông qua biến PATH để x c định xem file c n. .. sigsuspend(const sigset t *sigmask); int sigprocmask(int how, const sigset t *set, sigset_t *oset); Phần này chúng ta c 1 số bài tập như sau: 15 Viết 1 chương trình chặn ngắt SIGINT do nhấn phím Ctrl +C, đồng thời đếm số lần nhấn Ctrl +C khi chương trình chạy. _ ♦include ttinclude void catch(int signum) { static int count = 1; printf("\n An Ctrl -C lan thu:%d",count++);... if (access(argv[1],F_0K)= =-1 ) { printf("\n File doesnot exists"); return 1; } if (access(argv[1],R_OK)==0) { printf("\n file access OK"); return 0; } // tim thu muc cha hoac ong khong cho phep doc hoac thuc thi char buf[100]; char *ptr; char parent[100]; 11/44 int reason=0; int len=0; struct stat statbuf; //lay vi tri cuoi cung cua / ptr = strrchr(argv[ 1 ; len= ptr - argv[l]; //lay thu muc cha cua... char *open_mode); int pclose(FILE *stream_to_close); Hàm popen cho phép tiến trình đang chạy gọi 1 chương trình kh c chạy (sinh ra 1 tiến trình con) sau đó sẽ th c hiện vi c lấy ho c truyền dữ liệu cho tiến trình mới Tiến trình mới đư c gọi với tên chương trình chạy là const char *command Ví dụ sau minh họa cho c ch làm vi c: int maỉn() { FILE *read_fp; char buffer[BUFSIZ + 1]; int chars read; meraset(buffer,... ( char *pathname, char proj ); Trong phàn này chúng ta c 1 số bài tập như sau: 17 Viết chương trình minh họa chuyến đổi định hướng giữa 2 tiến trình cha và con sao cho đầu ra chuấn c a tiến trình này là đầu vào chuẩn c a tiến trình kia ệinclude ệinclude void do_child(int data_pipe[;) int c; int rc; { close(data_pipe[1]); while {(rc = read(data_pipet0], &c, 1)) > 0 ) putchar (c) ;... *stop=0; countries = (struct country*) ((void*)shm_addr+sizeof(int)*2); strcpy(countries[0].name, "U.S.A"); strcpy(countries[0].capital_city, "Washington"); strcpy(countries[0].currency, "U.S Dollar"); countries[0].population = 250000000; (*countries_num)++; strcpy(countries[1] name, "Israel"); strcpy(countries[1].capital_city, "Jerusalem"); strcpy(countries[1].currency, "New Israeli Shekel"); countries[1].population... %s:\n", countries[i].name); printf(" capital city: %s:\n", countries[i].capital_city); printf(" currency: %s:\n", countries[i].currency); printf (" population: %d:\n", countries[i].population); } printf("Now try to stop writer \n"); *Stop=l; return 0; ♦include ♦include ♦include ♦include struct country { char name[30]; char capital city[30]; 32/44 char currency[30]; . C c nội dung c n ôn tập với c Kiến th c chung Kiến th c lập trình c trong UNIX về c bản c ng giống như h c lập trình trong Borland c 3.1 c n gọi là phiên bản BC cho DOS) cho nên c c bạn c . dãy c c tiên trình với quan hệ cha con như sau: a. A -& gt; B -& gt; c -& gt; D : t c là A là cha c a B, B là cha c a c, c là cha c a D. b. A -& gt; (B, c, D ): t c là A là cha c a B, c, D. c. Xây. khảo c c c pháp c ng như c c hàm trong BC. Tuy nhiên chúng ta c ng c n nhấn mạnh 1 chút về c c vấn đề sau: • Program Arguments. int main(int argc, char *argv[]) . o Chú ý rằng argv[0] luôn c

Ngày đăng: 16/04/2014, 18:00

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan