2022年2022年精通linuxc编程 .pdf
3. 文件操作1、编写一个程序,打开一个文本文件,读取其中内容,将其复制到一个新建文件中。/filecopy.c #include #include #include #include #define PERMS 0666 #define DUMMY 0 #define BUFSIZE 1024 int main(int argc, char *argv) int source_fd, target_fd, num; char iobufferBUFSIZE; if(argc != 3) printf(参数个数不正确!n); return 1; if(source_fd = open(*(argv+1), O_RDONLY, DUMMY) = -1) printf(文件打开错误 !n); return 2; if(target_fd = open(*(argv+2), O_WRONLY|O_CREAT, PERMS) = -1) printf(创建文件失败! n); return 3; while(num = read(source_fd, iobuffer, BUFSIZE) 0) if(write(target_fd, iobuffer, num) != num) printf(文件写入失败 n); return 4; close(source_fd); close(target_fd); return 0; / 编译 gcc filecopy.c -o filecopy / 运行 ./filecopy filecopy.c filecopy副本 .c 2、编写一个程序,打开一个文件,将它截断至原来长度的1/2 。/filetruncate.c #include #include #include #include int main(int argc, char *argv) int i, fd; struct stat buf; if(argc != 2) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 20 页 - - - - - - - - - printf(参数个数不正确!n); return 1; if(fd = open(argv1, O_RDWR) 0) printf(%s 打开失败! n, argv1); return 2; if(fstat(fd, &buf) 0) printf(错误! ); return 3; else i = buf.st_size; printf(%s大小 :%d 字节 n, argv1, i); if(ftruncate(fd, i/2) 0) printf(%s截断失败! n, argv1); return 4; printf(%s截断成功 n, argv1); / 编译 gcc filetruncate.c -o filetruncate / 运行 ./filetruncate test.c 3、编写一个程序,打开一个文本文件,然后把此文件中小写字母转换为大写字母,其他字符不变。其中文件名作为命令行参数。/atoA.c #include #include #include #include #define BUFSIZE 1024 int main(int argc, char *argv) int fd, num, i; char iobufferBUFSIZE; if(argc != 2) printf(参数个数不正确!n); return 1; if(fd = open(*(argv+1), O_RDWR) = -1) printf(文件打开错误 !n); return 2; while(num = read(fd, iobuffer, BUFSIZE) 0) for(i = 0; i =a & iobufferi=z) iobufferi-=32; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 20 页 - - - - - - - - - lseek(fd, -num, SEEK_CUR); / 向前偏移文件指针if(write(fd, iobuffer, num) != num) printf(文件写入失败 n); return 3; close(fd); return 0; / 编译 gcc atoA.c -o atoA / 运行 ./atoA test.c 4、编写一个程序,读取当前工作目录下的内容,并将其打印输出到终端。/readwd.c #include #include #include #include #include int main(int argc, char *argv) char pathPATH_MAX + 1; DIR * dp; struct dirent *pdirent; if(argc!=1) printf(命令参数错误! n); return 1; if(getwd(path) = NULL) printf(获取当前工作目录失败!n); return 2; if(dp = opendir(path)=NULL) printf(打开 %s 失败 n, path); return 3; /printf(%sn, path); while(pdirent = readdir(dp) printf(%sn,pdirent-d_name); closedir(dp); return 0; / 编译 gcc readwd.c -o readwd / 运行 ./readwd 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 20 页 - - - - - - - - - 4. 标准 IO 库1、 编写一个程序,从键盘输入一个字符,并将其显示出来,当输入q 时,程序退出。/4_1.c #include int main(int argc, char *argv) char c; while(c = getchar() != q) putchar(c); return 0; / 编译 gcc 4_1.c -o 4_1 / 运行 ./4_1 2、 编写一个程序,打开一个文本文件,读入一行内容,然后在终端显示此行内容,其中文件名作为命令行参数。/4_2.c #include int main(int argc, char *argv) char buf1024; FILE *fp; if(argc != 2) printf(参数个数不正确!n); return 1; if(fp = fopen(argv1, r) = NULL) printf(文件读取失败 !n); return 2; fgets(buf, 1024, fp); puts(buf); return 0; / 编译 gcc 4_2.c -o 4_2 / 运行 ./4_2 4_2.c 3、 编写一个程序,打开一个文本文件,读入一行内容,然后把此行内容中的小写字母转换为大写字母,其他字符不变。其中文件名作为命令行参数。/4_3.c #include int main(int argc, char *argv) char buf1024; FILE *fp; int i = 0; if(argc != 2) printf(参数个数不正确!n); return 1; if(fp = fopen(argv1, r) = NULL) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 20 页 - - - - - - - - - printf(文件读取失败 !n); return 2; fgets(buf, 1024, fp); printf(读取 %s的第一行文本内容为:n, argv1); puts(buf); while(bufi != n) / 大小写转换 if(bufi =a & bufi=z) bufi-=32; i+; printf(转换大小写后的第一行文本内容为:n); puts(buf); return 0; / 编译 gcc 4_3.c -o 4_3 / 运行 ./4_3 4_3.c 4、 编写一个程序,从磁盘中输入字符,并将它写入一个临时文件,当输入q 时,程序退出。/4_4.c #include int main(int argc, char *argv) char c; FILE *fp; char tmpnameL_tmpnam; tmpnam(tmpname); if(fp = fopen(tmpname, w) = NULL) printf(临时文件 %s打开失败 n, tmpname); return 1; printf(正在写入临时文件%s,按q 结束 :n, tmpname); while(c = getchar() != q) fputc(c, fp); printf(已写入临时文件%sn, tmpname); return 0; / 编译 gcc 4_4.c -o 4_4 / 运行 ./4_4 5. 进程操作1、 编写一个程序,在主程序中创建一个子进程,子进程输出“Hello World!”字符串后退出,然后主进程退出。/5_1.c #include #include #include 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 20 页 - - - - - - - - - int main() pid_t pid; pid = vfork(); if(pid = 0) printf(Hello World!n); _exit(0); printf(子进程 %d已退出 n, pid); printf(父进程正在退出n); return 0; / 编译 gcc 5_1.c -o 5_1 / 运行 ./5_1 2、 编写一个程序,在主进程中创建一个子进程,子进程进行空循环,不停地输出“Hello World!”字符串,主进程休眠一段时间后,在主进程中结束子进程,随后主进程也退出。/5_2.c #include #include #include #include int main() pid_t pid; pid = fork(); if(pid = 0) while(1) printf(Hello World!); else sleep(1); kill(pid, SIGTERM); return 0; / 编译 gcc 5_2.c -o 5_2 / 运行 ./5_2 3、 编写一个程序,在程序中使用命令行形式显示程序所在当前文件夹下的内容。/5_3.c #include #include int main() system(ls); return 0; / 编译 gcc 5_3.c -o 5_3 / 运行 ./5_3 4、 编写一个程序,得到当前进程的标识号,并将它打印输出,随后写入一个文件中。/5_4.c #include 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 20 页 - - - - - - - - - #include #include int main(int argc, char *argv) FILE *fp; if(argc != 2) printf(参数个数不正确!n); return 1; int i = getpid(); printf(当前进程的标识号为:n%dn, i); if(fp = fopen(argv1, w) = NULL) printf(文件打开失败! n); return 2; / 整数转化为字符串char a1024; int bit = 0; while(i) /逆序写入数组 abit = i % 10 + 0; i = i / 10; bit+; while(bit)/从数组逆序读出 fputc(abit-1, fp); bit-; printf(已写入 %sn, argv1); fclose(fp); return 0; / 编译 gcc 5_4.c -o 5_4 / 运行./5_4 uid.txt 6. 进程间通信1、 编写一个程序,将用户从命令行指定的进程用SIGTERM 信号或指定的信号结束。/6_1.c #include #include int main( int argc, char *argv) if(argc != 2) printf(参数数目不正确!n); return 1; /argv1 char* - int int pid = 0; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 20 页 - - - - - - - - - int sign = 1; if(*argv1 = -) sign = -1; argv1+; else if(*argv1 = +) argv1+; while(*argv1) pid = pid * 10 +(*argv1 - 0); argv1+; pid *= sign; kill(pid, SIGTERM); printf(进程 %d已被 Kill!n, pid); return 0; / 编译 gcc 6_1.c -o 6_1 / 运行 ./6_1 498 2、 编写一个多客户 - 单一服务器模式的程序,用命名管道实现客户到服务器之间的传递数据的操作。/6_2_server.c #include #include #include #include #include #include #define BUFSIZE 80 #define FIFO_FILE MYFIFO int main() FILE *fp; char readbufBUFSIZE; if(fp = fopen(FIFO_FILE, r) = NULL) umask(0); mknod(FIFO_FILE, S_IFIFO | 0666, 0); else fclose(fp); while(1) if(fp = fopen(FIFO_FILE, r) = NULL) printf(打开命名管道失败n); return 1; if(fgets(readbuf, BUFSIZE, fp) != NULL) printf(接受到字符串 :%sn,readbuf); if(strncmp(readbuf, quit, 4) = 0) break; fclose(fp); else 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 20 页 - - - - - - - - - if(ferror(fp) printf(读取命名管道失败!n); return 2; fclose(fp);/! return 0; / 编译 gcc 6_2_server.c -o 6_2_server / 运行./6_2_server /6_2_client.c #include #include #define BUFSIZE 80 #define FIFO_FILE MYFIFO int main(int argc, char *argv) FILE *fp; int i; if(argc = 1) printf(请带上要发送的内容n); return 1; if(fp = fopen(FIFO_FILE, w) = NULL) printf(打开命名管道错误n); return 2; for(i = 1; i argc; i+) if(fputs(argvi, fp) = EOF) printf(写命名管道失败.n); return 3; if(fputs( , fp) = EOF) printf(写命名管道失败.n); return 3; fclose(fp); return 0; / 编译gcc 6_2_client.c -o 6_2_client / 运行 ./6_2_client Hello World! 3、 编写用消息队列进行通信的程序,其中一个进程负责对入文本文件的内容,另一个进程负责显示读取的内容。/6_3_readFile.c #include #include #include #include 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 20 页 - - - - - - - - - #include #include #include #include #include #define BUFSIZE 512 #define MSQKEY 1234 struct mymsg long int mymsgtype; char textBUFSIZE; msgbuf; int main(int argc, char *argv) int fd, num, msqid; char iobufferBUFSIZE; if(argc != 2) printf(参数个数不正确!n); return 1; if(fd = open(*(argv+1), O_RDONLY, 0) = -1) printf(指定文件打开错误!n); return 2; if(msqid = msgget(key_t)MSQKEY, 0666|IPC_CREAT) = -1) printf(消息队列创建或打开失败!n); return 3; while(num = read(fd, iobuffer, BUFSIZE) 0) msgbuf.mymsgtype = 1; strcpy(msgbuf.text, iobuffer); if(msgsnd(msqid, (void *)&msgbuf, BUFSIZE, 0) = -1) printf(读取的文件内容发送失败!n); return 4; / 发送结束标识strcpy(msgbuf.text, end); msgsnd(msqid, (void *)&msgbuf, BUFSIZE, 0); return 0; / 编译 gcc 6_3_readFile.c -o 6_3_readFile / 运行 ./6_3_readFile test /6_3_showFile.c #include #include #include #include #include #include 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 20 页 - - - - - - - - - #include #include #define BUFSIZE 512 #define MSQKEY 1234 struct mymsg long int mymsgtype; char textBUFSIZE; msgbuf; int main() int msqid; if(msqid = msgget(key_t)MSQKEY, 0666|IPC_CREAT) = -1) printf(消息队列创建或打开失败!n); return 1; printf(从消息队列中读取到的文本内容为:n); while(1) if(msgrcv(msqid, (void *)&msgbuf, BUFSIZE, 0, 0) = -1) printf(消息接受失败 ); return 2; if(strncmp(msgbuf.text, end, 5) = 0) break; printf(%s, msgbuf.text); return 0; / 编译 gcc 6_3_showFile.c -o 6_3_showFile / 运行 ./6_3_showFile 7. 线程操作1、 编写一个包含2 个线程的程序,在主线程中创建一个全局变量并初始化为0,在另一个线程对这个全局变量进行递加运算,并在结束时向主线程返回一个结果,由主线程打印输出。/7_1.c #include #include #include #include int *nn; int n = 0; void* add() int i; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 20 页 - - - - - - - - - for(i = 0; i 20; i+) n+; return (void *)(&n); int main() pthread_t thread; pthread_create(&thread, NULL, (void *)(&add), NULL); pthread_join(thread, (void *)&nn); printf(%dn,*nn); return 0; / 编译 gcc -pthread 7_1.c -o 7_1 / 运行 ./7_1 2、 编写一个包含2 个线程的程序,在主线程中接受键盘输入,并把输入字符放入缓冲区中,在缓冲区满后,由另一个线程输出缓冲区的内容,用互斥锁实现二者之间的同步。/7_2.c #include #include #include #include #include void writefun(); void readfun(); char buffer10; int r = 0; pthread_mutex_t mutex; int main() pthread_t read, write; void *retval; pthread_mutex_init(&mutex, NULL); pthread_create(&read, NULL, (void *)(&readfun), NULL); pthread_create(&write, NULL, (void *)(&writefun), NULL); pthread_join(write, &retval); pthread_join(read, &retval); return 0; void writefun() int i, bj = 0; char b100; pthread_mutex_lock(&mutex); while(1) if(buffer9) break; scanf(%s,b); for(i = 0; i strlen(b); i+, bj+) bufferbj = bi; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 12 页,共 20 页 - - - - - - - - - if(bj = 9) break; r = 1; pthread_mutex_unlock(&mutex); void readfun() while(1) if(r) printf(%sn, buffer); break; / 编译 gcc -pthread 7_2.c -o 7_2 / 运行 ./7_2 3、 用条件变量重新编写例7-2 程序。/7_3.c #include #include #include #include #include void print_msg(char *ptr); sem_t sem1; int j = 0; int main() pthread_t thread1, thread2; void *retval; char *msg1 = Hello ; char *msg2 = World ; sem_init(&sem1, 0, 0); pthread_create(&thread1, NULL, (void *)(&print_msg), (void *)msg1); sem_wait(&sem1); pthread_create(&thread2, NULL, (void *)(&print_msg), (void *)msg2); /pthread_join(thread1, &retval); /pthread_join(thread2, &retval); sleep(1); return 0; void print_msg(char *ptr) int i; sem_post(&sem1); for(i = 0; i 200; i+) printf(%s, ptr); j+; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 13 页,共 20 页 - - - - - - - - - / 编译 gcc -pthread 7_3.c -o 7_3 / 运行./7_3 4、 编写一个程序,在主线程中创建一个新线程,在主线程中得到新线程的各个属性,并在主线程中将它们打印输出。/7_4.c #include #include #include #include void *my_thread(void *arg) int retval=0; pthread_attr_t attr; struct sched_param param; size_t stacksize; int detachstate; int scope; int inherit; int policy; if(pthread_attr_init(&attr)=0) if(pthread_attr_getstacksize(&attr,&stacksize)=0) printf(新建线程堆栈大小: %dn,stacksize); if(pthread_attr_getdetachstate(&attr, &detachstate)=0) if(detachstate=PTHREAD_CREATE_JOINABLE) printf(新建线程的拆卸状态: PTHREAD_CREATE_JOINABLEn); if(detachstate=PTHREAD_CREATE_DETACHED) printf(新建线程的拆卸状态: PTHREAD_CREATE_DETACHEDn); if(pthread_attr_getscope(&attr, &scope)=0) if(scope=PTHREAD_SCOPE_PROCESS) printf(新建线程的作用域: PTHREAD_SCOPE_PROCESSn); if(detachstate=PTHREAD_SCOPE_SYSTEM) printf(新建线程的作用域: PTHREAD_SCOPE_SYSTEMn); if(pthread_attr_getinheritsched(&attr, &inherit)=0) if(inherit=PTHREAD_INHERIT_SCHED) printf(新建线程的继承性: PTHREAD_INHERIT_SCHEDn); if(inherit=PTHREAD_EXPLICIT_SCHED) printf(新建线程的继承性: PTHREAD_EXPLICIT_SCHEDn); if(pthread_attr_getschedpolicy(&attr, &policy)=0) if(policy=SCHED_FIFO) printf(新建线程的调度策略: SCHED_FIFOn); if(policy=SCHED_RR) printf(新建线程的调度策略: SCHED_RRn); else printf(新建线程的调度策略: SCHED_OTHERn); if(pthread_attr_getschedparam(&attr, ¶m)=0) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 14 页,共 20 页 - - - - - - - - - printf(新建线程的调度参数: %dn,param.sched_priority); pthread_attr_destroy(&attr); pthread_exit(&retval); int main() int count; pthread_t thread; int *retval; if(pthread_create(&thread,NULL,my_thread,(void *)NULL)!=0) printf(创建线程失败 !n); return -1; if(pthread_join(thread,(void *)(&retval)!=0) printf(没有线程可等待 !n); return -2; return 0; / 编译 gcc -pthread 7_4.c -o 7_4 / 运行 ./7_4 8.网络编程1、 编写一个程序,测试一下本机存储整数的方式是little-endian方式还是 big-endian方式。/8_1.c #include #include #include int main() union short inum; char csizeof(short); un; struct utsname uts; un.inum = 0 x0102; if(uname(&uts) 0) printf(获取主机信息失败!n); return 1; printf(%s-%s-%s:n, uts.machine, uts.sysname, uts.release); if(sizeof(short) != 2) printf(sizeof(short) = %dn, sizeof(short); return 0; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 15 页,共 20 页 - - - - - - - - - if(un.c0 = 1 & un.c1 = 2) printf(big_endian.n); else if(un.c0 = 2 & un.c1 = 1) printf(little_endian.n); else printf(unknown.n); return 0; / 编译 gcc 8_1.c -o 8_1 / 运行./8_1 2、 编写一个数据流客户端/ 服务器程序,服务器程序在与客户端程序建立连接后,返回服务器的时间,客户端程序在接收后将时间显示出来。/8_2_s.c #include #include #include #include #include #include #include #define PORT 7777 int main() int listenfd, connfd; socklen_t len; time_t ticks; char buff512; struct sockaddr_in addr, raddr; if(listenfd = socket(AF_INET, SOCK_STREAM, 0) 0) printf(创建套接字错误 !n); return 1; addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(listenfd, (struct sockaddr *)&addr, sizeof(addr) 0) printf(绑定套接字失败 !n); return 2; printf(监听中 .n); listen(listenfd, 5); len = sizeof(raddr); connfd = accept(listenfd, (struct sockaddr *)&raddr, &len); printf(已发送服务器当前时间n); ticks = time(NULL); sprintf(buff, %.24sn, ctime(&ticks); write(connfd, buff, strlen(buff); close(connfd); close(listenfd); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 16 页,共 20 页 - - - - - - - - - return 0; / 编译 gcc 8_2_s.c -o 8_2_s / 运行 ./8_2_s /8_2_c.c #include #include #include #include #define PORT 7777 int main() int sockfd, n; char recvbuff512; struct sockaddr_in servaddr; if(sockfd = socket(AF_INET, SOCK_STREAM, 0) 0) printf(套接字创建失败 !n); return 1; servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); printf(连接服务器中 .n); if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr) 0) recvbuffn = 0; fputs(recvbuff, stdout); if(n 0) printf(读取数据失败 !n); return 3; return 0; / 编译 gcc 8_2_c.c -o 8_2_c / 运行 ./8_2_c 3、 编写一个数据流客户端/ 服务器程序, 其中客户端接受键盘输入并发送到服务器,服务器把输入内容显示出来。/8_3_s.c #include #include #include #include #include #include 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 17 页,共 20 页 - - - - - - - - - #define PORT 7779 int main() int listenfd, connfd, n; socklen_t