Linux操作系统下c语言编程入门 if(s_ ISDIR(statbuf st_mode ))return(1) if(s_ISREG(statbufst_mode)) printf("%s size: %ld bytes\modified at %St filename statbufst_size, ctime(&statbufst_mtime); eturn(O) int main (int argc, har **argv) struct dirent*direntp int stats, if(agcl=2) printf("Usage: %S filename\\a', argv[OD; if(((stats=get_file-size_time argv[ l)==o)l(stats==-1)exit(1); if((dirp=opendirargv[1)==NULL) ror strerrorferrno ext(1)}; while((direntp=readdir(dirp)=NULL) if(get_file_size_time(direntp-<d_name)==-1)break, closedir(dirp) 4。管道文件 Linux提供了许多的过滤和重定向程序比如 more cat 等等还提供了<>1<<等等重定向操作符在这些过滤和重定向程序当中都用到了管 道这种特殊的文件系统调用 pipe可以创建一个管道 #include <unistd.h> int pipe(int fildes[2]); pipe调用可以创建一个管道(通信缓冲区).当调用成功时,我们可以访问文件描述符fd es[0J, fildes[1]其中fdes[O]是用来读的文件描述符,而fdes[1]是用来写的文件描 述符 在实际使用中我们是通过创建一个子进程然后一个进程写,一个进程读来使用的 关于进程通信的详细情况请查看进程通信 #include <stdio. h> #include <stdlib. h> 第16页共84页
Linux 操作系统下 c 语言编程入门 } if(S_ISDIR(statbuf.st_mode))return(1); if(S_ISREG(statbuf.st_mode)) printf(“%s size:%ld bytes\tmodified at %s”, filename,statbuf.st_size,ctime(&statbuf.st_mtime)); return(0); } int main(int argc,char **argv) { DIR *dirp; struct dirent *direntp; int stats; if(argc!=2) { printf(“Usage:%s filename\n\a”,argv[0]); exit(1); } if(((stats=get_file_size_time(argv[1]))==0)||(stats==-1))exit(1); if((dirp=opendir(argv[1]))==NULL) { printf(“Open Directory %s Error:%s\n”, argv[1],strerror(errno)); exit(1); } while((direntp=readdir(dirp))!=NULL) if(get_file_size_time(direntp-<d_name)==-1)break; closedir(dirp); exit(1); } 4。管道文件 Linux 提供了许多的过滤和重定向程序,比如 more cat 等等.还提供了< > | <<等等重定向操作符.在这些过滤和重 定向程序当中,都用到了管 道这种特殊的文件.系统调用 pipe 可以创建一个管道. #include<unistd.h> int pipe(int fildes[2]); pipe 调用可以创建一个管道(通信缓冲区).当调用成功时,我们可以访问文件描述符 fild es[0],fildes[1].其中 fildes[0]是用来读的文件描述符,而 fildes[1]是用来写的文件描 述符. 在实际使用中我们是通过创建一个子进程,然后一个进程写,一个进程读来使用的. 关于进程通信的详细情况请查看进程通信 #include <stdio.h> #include <stdlib.h> 第 16 页 共 84 页
Linux操作系统下c语言编程入门 #include <unistd. h> #include <string.h> #include <errno. h> #include <sys/wait. h> #define buffer 255 int main (int argc, char **argv) char buffer[BUFFER+1 int fd[2: if(argc!=2) fprintf(stderr," Usage: % s string\n a,argv[oD; if(pipe(fd)!=D) fprintf(stderr, "Pipe Error: %s\n\a"strerror(errno)) exit(1); if(forko==0) printf( Child[d] Write to pipe\\,getpido: snprintf(buffer, BUFFER, "%s, argv[1]); write(fd[1], buffer strlen(buffer)) printf("Child[%d] Quit\n\agetpido) close(fd[1D; printf("Parent[%d] Read from pipewnla, getpido: memset(buffer, \0, BUFFER+1) read(fd[o, buffer, BUFFER) printf( Parent[%d] Read: %s\n getpido, buffer); exit(1) 为了实现重定向操作我们需要调用另外一个函数dup2 #indlude <unistd.h> int dup2(int oldfd, nt newfd) dup2将用 oldfd文件描述符来代替newd文件描述符,同时关闭 newfd文件描述符也就是说 第17页共84页
Linux 操作系统下 c 语言编程入门 #include <unistd.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/wait.h> #define BUFFER 255 int main(int argc,char **argv) { char buffer[BUFFER+1]; int fd[2]; if(argc!=2) { fprintf(stderr,”Usage:%s string\n\a”,argv[0]); exit(1); } if(pipe(fd)!=0) { fprintf(stderr,”Pipe Error:%s\n\a”,strerror(errno)); exit(1); } if(fork()==0) { close(fd[0]); printf(“Child[%d] Write to pipe\n\a”,getpid()); snprintf(buffer,BUFFER,”%s”,argv[1]); write(fd[1],buffer,strlen(buffer)); printf(“Child[%d] Quit\n\a”,getpid()); exit(0); } else { close(fd[1]); printf(“Parent[%d] Read from pipe\n\a”,getpid()); memset(buffer,'\0',BUFFER+1); read(fd[0],buffer,BUFFER); printf(“Parent[%d] Read:%s\n”,getpid(),buffer); exit(1); } } 为了实现重定向操作,我们需要调用另外一个函数 dup2. #include <unistd.h> int dup2(int oldfd,int newfd); dup2 将用 oldfd 文件描述符来代替 newfd 文件描述符,同时关闭 newfd 文件描述符.也就是说 第 17 页 共 84 页
Linux操作系统下c语言编程入门 所有向 newfd操作都转到odfd上面.下面我们学习一个例子,这个例子将标准输出重定向 到一个文件 #indlude <stdio h> #include <errno h> #include <string. h> #include <sys/types.h> #include <sys/stat. h> #define BUFFER size 1024 int main (int argc, char **argv) char buffer[BUFFER_SIzE if(argc!=2) fprintf( stderr,"Usage: %s outfilenamen\a,argv[OD: t(1) if((fd=open (argv[1],o_WRONLYIO_CREATO_TRUNC S IRUSRIS_IWUSR))==-1 fprintf(stderr,"Open %S Error: %s\n\aargvl1], strerror(errno)); exit(1); if(dup2(fd, STDOUT_ FILENO==-1) fprintf(stderr,"Redirect Standard Out Error: %s\n\astrerrorerrno)) exit(1) fprintf(stderr, " Now, please input string fprintf(stderr, (To quit use CTRL+D)\n); while(1) fgets(buffer, BUFFER_SIZE, Stdin); if(feof(stdin))break write(STDOUT_FILENo, buffer strlen(buffer)) 好了文件一章我们就暂时先讨论到这里学习好了文件的操作我们其实已经可以写出一 些比较有用的程序了我们可以编写一个实现例如 dir, mkdir, cp,m等等常用的文件操作 命令了 想不想自己写几个试一试呢? 第18页共84页
Linux 操作系统下 c 语言编程入门 , 所有向 newfd 操作都转到 oldfd 上面.下面我们学习一个例子,这个例子将标准输出重定向 到一个文件. #include <unistd.h> #include <stdio.h> #include <errno.h> #include <fcntl.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #define BUFFER_SIZE 1024 int main(int argc,char **argv) { int fd; char buffer[BUFFER_SIZE]; if(argc!=2) { fprintf(stderr,”Usage:%s outfilename\n\a”,argv[0]); exit(1); } if((fd=open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR))==-1) { fprintf(stderr,”Open %s Error:%s\n\a”,argv[1],strerror(errno)); exit(1); } if(dup2(fd,STDOUT_FILENO)==-1) { fprintf(stderr,”Redirect Standard Out Error:%s\n\a”,strerror(errno)); exit(1); } fprintf(stderr,”Now,please input string”); fprintf(stderr,”(To quit use CTRL+D)\n”); while(1) { fgets(buffer,BUFFER_SIZE,stdin); if(feof(stdin))break; write(STDOUT_FILENO,buffer,strlen(buffer)); } exit(0); } 好了,文件一章我们就暂时先讨论到这里,学习好了文件的操作我们其实已经可以写出一 些比较有用的程序了.我们可以编写一个实现例如 dir,mkdir,cp,mv 等等常用的文件操作 命令了. 想不想自己写几个试一试呢? 第 18 页 共 84 页
Linux操作系统下c语言编程入门 4) Linux程序设计入门-时间概念 前言: Linux下的时间概念 这一章我们学习Lnu的时间表示和计算函数 时间的表示 时间的测量 计时器的使用 1。时间表示在程序当中我们经常要输出系统当前的时间,比如我们使用date命令 的输出结果这个时候我们可以使用下面两个函数 #include <time. h> time_t time(time_t *tloc); char *ctime(const time_t*clock); tme函数返回从1970年1月1日0点以来的秒数存储在tmet结构之中不过这个函数的返 回值对于我们来说没有什么实际意义这个时候我们使用第二个函数将秒数转化为字符串 这个函数的返回类型是固定的:一个可能值为. Thu Dec71458:592000这个字符串 的长度是固定的为26 2。时间的测量有时候我们要计算程序执行的时间比如我们要对算法进行时间分析 这个时候可以使用下面这个函数 #include <sys/time.h> int gettimeofday(struct timeval *tv, struct timezone* tz) strut timeval t long tv_ sec;/*秒数 long tv_usec;/*微秒数* } gettimeofday将时间保存在结构t之中一般我们使用NULL来代替 #include <sys/time. h< #include <stdio. h #include <math. h< void function unsigned int i, for(=0;i<1000++ y=sin((double)i) maino struct timeval tpstart, tend float timeuse unction 第19页共84页
Linux 操作系统下 c 语言编程入门 4)Linux 程序设计入门--时间概念 前言:Linux 下的时间概念 这一章我们学习 Linux 的时间表示和计算函数 时间的表示 时间的测量 计时器的使用 1。时间表示 在程序当中,我们经常要输出系统当前的时间,比如我们使用 date 命令 的输出结果.这个时候我们可以使用下面两个函数 #include <time.h> time_t time(time_t *tloc); char *ctime(const time_t *clock); time 函数返回从 1970 年 1 月 1 日 0 点以来的秒数.存储在 time_t 结构之中.不过这个函数的返 回值对于我们来说没有什么实际意义.这个时候我们使用第二个函数将秒数转化为字符串 .. 这个函数的返回类型是固定的:一个可能值为. Thu Dec 7 14:58:59 2000 这个字符串 的长度是固定的为 26 2。时间的测量 有时候我们要计算程序执行的时间.比如我们要对算法进行时间分析 ..这个时候可以使用下面这个函数. #include <sys/time.h> int gettimeofday(struct timeval *tv,struct timezone *tz); strut timeval { long tv_sec; /* 秒数 */ long tv_usec; /* 微秒数 */ }; gettimeofday 将时间保存在结构 tv 之中.tz 一般我们使用 NULL 来代替. #include <sys/time.h< #include <stdio.h< #include <math.h< void function() { unsigned int i,j; double y; for(i=0;i<1000;i++) for(j=0;j<1000;j++) y=sin((double)i); } main() { struct timeval tpstart,tpend; float timeuse; gettimeofday(&tpstart,NULL); function(); 第 19 页 共 84 页
Linux操作系统下c语言编程入门 gettimeofday ( &tpend, NULL) timeuse=1000000 (tend tv_ sec-tpstart tv_sec)+ tend tv_usec-tpstart tv_usec; printf( Used Time: %f\n, timeuse) 这个程序输出函数的执行时间,我们可以使用这个来进行系统性能的测试,或者是函数算 法的效率分析在我机器上的一个输出结果是: Used time:0.556070 3。计时器的使用Lnux操作系统为每一个进程提供了3个内部间隔计时器 ITIMER REAL:减少实际时间到时的时候发出 SIGALRM信号 ITIMER VIRTUAL:减少有效时间(进程执行的时间)产生 SIGVTALRM信号 ITIMER PROF:减少进程的有效时间和系统时间(为进程调度用的时间)这个经常和上面一 个使用用来计算系统内核时间和用户时间产生 SIGPROF信号 具体的操作函数是 #indlude <sys/time. h> int setitimer(int which, struct itimerval he, int getitimer(int which, struct itimerval *value); struct itimerval * oldval) struct itimerval t struct timeval it_ interval; struct timeval it value gettier函数得到间隔计时器的时间值保存在va|ue中 setitimer函数设置间隔计时器 的时间值为newa并将旧值保存在odva中. which表示使用三个计时器中的哪一个 itimerval结构中的 it value是减少的时间,当这个值为0的时候就发出相应的信号了.然 后设置为 it interva值 #include <sys/time. h> #include <stdio. h #include <unistd. h> #include <string.h> # define prompt"时间已经过去了两秒钟na har*prompt=PROMPT: unsigned int len void prompt_info(int signo) write(STDERR_FILENO, prompt, len; void init_ sigaction(void) struct sigaction act; act. sa_handler=prompt_info act. sa_flags=0 第20页共84页
Linux 操作系统下 c 语言编程入门 gettimeofday(&tpend,NULL); timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+ tpend.tv_usec-tpstart.tv_usec; timeuse/=1000000; printf(“Used Time:%f\n”,timeuse); exit(0); } 这个程序输出函数的执行时间,我们可以使用这个来进行系统性能的测试,或者是函数算 法的效率分析.在我机器上的一个输出结果是: Used Time:0.556070 3。计时器的使用 Linux 操作系统为每一个进程提供了 3 个内部间隔计时器. ITIMER_REAL:减少实际时间.到时的时候发出 SIGALRM 信号. ITIMER_VIRTUAL:减少有效时间(进程执行的时间).产生 SIGVTALRM 信号. ITIMER_PROF:减少进程的有效时间和系统时间(为进程调度用的时间).这个经常和上面一 个使用用来计算系统内核时间和用户时间.产生 SIGPROF 信号. 具体的操作函数是: #include <sys/time.h> int getitimer(int which,struct itimerval *value); int setitimer(int which,struct itimerval *newval, struct itimerval *oldval); struct itimerval { struct timeval it_interval; struct timeval it_value; } getitimer 函数得到间隔计时器的时间值.保存在 value 中 setitimer 函数设置间隔计时器 的时间值为 newval.并将旧值保存在 oldval 中. which 表示使用三个计时器中的哪一个. itimerval 结构中的 it_value 是减少的时间,当这个值为 0 的时候就发出相应的信号了. 然 后设置为 it_interval 值. #include <sys/time.h> #include <stdio.h> #include <unistd.h> #include <signal.h> #include <string.h> #define PROMPT “时间已经过去了两秒钟\n\a” char *prompt=PROMPT; unsigned int len; void prompt_info(int signo) { write(STDERR_FILENO,prompt,len); } void init_sigaction(void) { struct sigaction act; act.sa_handler=prompt_info; act.sa_flags=0; 第 20 页 共 84 页