1. Trang chủ
  2. » Giáo án - Bài giảng

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 586 0
Tài liệu đã được kiểm tra trùng lặp

Đ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

Thông tin cơ bản

Tiêu đề Các Nội Dung Cần Ôn Tập Với C Trong Khi Học C
Trường học University of Science and Technology of Hanoi
Chuyên ngành Computer Science
Thể loại Giáo án - Bài giảng
Năm xuất bản 2024
Thành phố Hà Nội
Định dạng
Số trang 44
Dung lượng 718,23 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Các nội dung cần ôn tập với c Kiến thức chungKiế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

Trang 1

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

Trang 2

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

Trang 3

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

Trang 4

#include <sys/stat.h>

int stat(const char *restrict pathname, struct stat *restrict buf);

int fstat(int filedes, struct stat *buf);

struct stat {

m o d e t stm od e; /* 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 stsiz e ; /* 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);

s s iz e t 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:

Trang 5

int mkdir(const char *pathname, mode_t mode);

struct dirent

{

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);

s i z e t fread(void *ptr, size_t size, size_t nitems, FILE *stream);

s i z e t 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 *form at, );

int scanf(const char *format, );

int fscanf(FILE *stream, const char *form at, );

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);

Trang 6

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).

char* file_path_from; /* source path */

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]);

while (fgets(buf, MAX_LINE_LEN+1, f_from)) {

if (fputs(buf, f_to) == EOF) {

fprintf(stderr, "Error writing to target file:

Trang 7

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.

strcat(output,mode); sprintf(temp," %s ", ctime(Sstatbuf.st_ctime));

strcat(output,temp); strcat(output," "); strcat(output,argv[0]); return 0;

Trang 8

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 đó. _

int fd = open(argv[1], 0_RD0NLY);

struct stat statbuf;

Trang 9

#include <sys/stat.h>

void printdir(char *dir, int depth)

{

DIR *dp;

struct dirent *entry;

struct stat statbuf;

struct dirent *entry;

struct stat statbuf;

Trang 11

exit (1);

p_slash = file_path;

while ( (p_slash = strchr(p_slash, '/')) != NULL) {

strncpy(dir_path, file_path, p_slash-file_path+l);

dir_path[p_slash-file_path+l] = '\0';

if (access(dir_path, F_OK) == -1) {

printf ("%s: Directory '%s' in the path does

not exist.\n","ACCESS DENIED", dir_path);exit(2);

}

if (access(dir_path, X_OK) == -1) {

printf ("%s: Directory '%s' in the path - no 'X'

permission.\n","ACCESS DENIED", dir_path);exit (2);

Trang 12

int reason=0;

int len=0;

struct stat statbuf;

//lay vi tri cuoi cung cua /

strcpy(parent,buf); //luu thu muc gay loi

reason = 0 ; //khong C O quyen doc

}

else if (! (statbuf.st_mode & S_IEXEC))

{

strcpy(parent,buf); //luu thu muc gay loi

reason = 1; //khong CO quyen thuc thi

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 thực hiện có nằm ở một trong các đường dẫn trong PATH không Hãy viết chương trình minh họa công việc này. _

Trang 13

II neu khong ton tai thi tim kiem trong bien moi truong PATH

buf = (char * ) malloc (256);

// khong tim thay

printf("\n File not exists");

return 0;

J _

Làm việc với tiến trình

Khi làm việc với tiến trình thì trước tiên ta quan tâm đến các thông tin về tiến trình cũng như các cách tạo ra tiến trình Các lời gọi hệ thống sau làm việc với tiến trình:

Tạo các tiến trình con:

int system (const char *string);

pid t fork(void);

pid t wait(int *statloc);

pid t waitpid(pid_t pid, int *stat!oc, int options);

int execl(const char *path, const char * a r g 0 , ( c h a r *)0);

int execlp(const char *file, const char * a r g 0 , ( c h a r *)0);

int execle(const char *path, const char * a r g 0 , ( c h a r *)0, const char *envp[]); int execv(const char *path, const char *argvf]);

int execvp(const char *tile, const char *argv[]);

int execve(const char *path, const char *argv[], const char *envp[]);

re tu rn 0;

}

Với các hàm này, chúng ta có 1 số bài tập đơn giản như sau:

Trang 14

11 Tạo 1 tiến trình con bằng hàm FORK và xác định các thông tin của tiến trình cha và tiến trình con (PID,PPID, UID, EUID, GID, EGID).

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.

Trang 15

Default : p3b = fork(); //sinh 3b tu 0

P2a = fork(); //sinh 2a tu 0

If (p2a = = 0) p3a = fork.(); //sinh 3a tu 2a}

Trang 16

re tu rn 0;

}

14 Viết chương ừình minh họa công việc chuyển hướng vào ra Ví dụ như: Đọc dừ liệu từ

_ file /etc/passwd sau đỏ sấp xếp các hảng theo cột tên ngừơi dùng (cột thứ nhất). _

void (*signal(int sig, void (*func)(int)))(int);

#defme SIG_ERR (void (*)())-1 ; #define SIG DFL (void (*)()) 0;

#define SIG JG N (void (*)()) 1

int kill(pid_t pid, int sig);

unsigned int alarm(unsigned int seconds);

int pause(void);

in t sigaction(int sig, const stru c t sigaction *act, stru ct sigaction *oact);

struct sigaction

{

void (*sa_handler)(int); /* addr of signal handler, */

sigset t sa mask; I* additional signals to block */

int sa flags; /* signal options*/

void (*sa_sigaction)(int, siginfo t *, void *);

};

Trang 17

int sigaddset(sigset_t *set, int signo);

int sigemptyset(sigset_t *set);

int sigfillset(sigset_t *set);

int sigdelset(sigset_t *set, int signo);

int sigismember(sigset_t *set, int signo);

int sigpending(sigset_t *set);

int 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 <stdio.h>

ttinclude <signal.h>

void catch(int signum)

{

static int count = 1;

printf("\n An Ctrl-C lan thu:%d",count++);

Trang 18

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)

Trang 19

static void sig_alrm(int signo)

struct sigaction newact, oldact;

sigset_t newmask, oldmask, suspmask;

unsigned int unslept;

/* set our handler, save previous information */

newact.sahandler = sigalrm ;

sigemptyset(&newact.sa_mask);

newact.sa flags = 0;

sigaction(SIGALRM, &newact, &oldact);

/* block SIGALRM and save current signal mask *1

sigemptyset(&newmask);

sigaddset(&newmask, SIGALRM);

sigprocraask(SIG_BLOCK, &newmask, &()Idmask);

alarm(nsecs); <- sử dụng hàm ALARM và SIGALRM để xây dụng SLEEP

sigaction(SIGALRM, &oldact, NULL); /* reset previous action */

/* reset signal mask, which unblocks SIGALRM */

sigprocmask(SIG_SETMASK, &oldmask, NULL);

FILE *popen(const char ^command, const char *open_mode);

int pclose(FILE *stream_to_close);

Trang 20

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 pipe(int file_descriptor[2]);

int mkfifo(const char ^filename, mode_t mode);

int mknod(const char *filename, mode t mode I S IFIFO, (dev t) 0);

key t ftok ( 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.

Trang 22

18 Viet 2 chương trình có nhiệm vụ như sau:

a Tiến trình A là tiến trình tạo dữ liệu, ví dụ nó tạo ra các xâu ký tự.

b Tiến trình B là tiến trinh xử lý dữ liệu, ví dụ như in ra màn hình xâu ký tự

c Tiến trình A gửi dừ liệu cho tiến trình B.

Hãy minh họa công việc trên bằng cách sử dụng FIFO (named pipe).

#define FIFO_NAME "/tmp/my_fifo"

#define BUFFER_SIZE PIPE_BUF

}

printf("Process %d opening FIFO 0_WR0NLY\n",

g

etpid()) ;

Trang 23

pipe_fd = open(FIFO_NAME, open_mode);

printf("Process %d result %d\n", getpid(), pipe_fd);

if (pipe_fd != -1) {

while(bytes_sent < ?EN_MEG) {

res = write (pipe_fd, buffer, BUFFERjSIZE);

if (res == -1) {fprintf(stderr, "Write error on pipe\n");

exit(EXIT_FAILURE);

}bytes_sent += res;

ttdefine FIFO_NAME "/tmp/my_fifo"

#define BUFFER_SIZE PIPE_BUF

pipe_fd = open(FIFO_NAME, open_mode);

printf ("Process %d result %d\n”, getpidO, pipe_fd) ;

}

P r o g A c

Trang 24

#include <unistd.h>

#include <stdio.h>

#include <signal.h>

#define FIFO_NAME "/tmp/testfifo"

int main(int argc,char *argv]])

{

int fd;

if (access(FIF0_NAME,F_0K)==-1)

if (mkfifo(FIFO_NAME,0777) != 0 ){

♦define FIFO_NAME "/tmp/testfifo"

int main(int argc,char *argv[])

Trang 25

int msgctl(int msqid, int cmd, struct ms qi dds *buf);

int msgget(key_t key, int msgflg);

int msgrcv(int msqid, void *msg_ptr, s i z e t ms g s z , long int msgtype, int msgflg); int msgsnd(int msqid, const void *msg_ptr, size t msg sz, int msgflg);

struct msqid ds

{

struct ipc_perm msg perm;

struct msg *msg_first; /* first message on queue, unused */

struct msg *msg_last; /* last message in queue, unused */

_kernel_time_t msg stime; /* last msgsnd time */

_kernel_time_t msg rtime; /* last msgrcv time *1

_kernel_time_t msg ctime; /* last change time */

unsigned long msg lcbytes: /* Reuse junk fields for 32 bit */

unsigned long m sglqbytes; /* ditto */

unsigned short msg cbytes; /* current # of bytes on queue */

unsigned short msg qnum; /* number of messages in queue */

unsigned short msg qbytes; /* max number of bytes on queue */

kernel_ipc_pid_t msg lspid; /* pid of last msgsnd */

_kernel_ipc_pid_t msg lrpid; /* last receive pid */

long mtype; /* type of message */

char mtextfl]; /* message text */

1;

/* Owner's user ID */

/* Owner's group ID */

/* Creator's user ID */

/* Creator's group ID */

/* Access permission */

Trong phần này chúng ta có 1 số bài tập như sau:

19 Xây dựng chương trình quản lý Message Queue như:

a Tạo, hủy đối tượng Message Queue.

b Ghi, đọc thông điệp từ hàng đợi.

c Đọc các thông tin của Message Queue như: quyền truy cập, người sử dụng, .

20 Viết 2 chương trình trao đối dữ liệu với nhau thông qua Message Queue.

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

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w