现在的位置: 首页 > 综合 > 正文

APUE2 1.1-1.6

2017年11月23日 ⁄ 综合 ⁄ 共 2306字 ⁄ 字号 评论关闭
#include "apue.h"
#include <dirent.h>

int
main(int argc, char *argv[])
{
    DIR             *dp;
    struct dirent   *dirp;

    if (argc != 2)
        err_quit("usage: ls directory_name");

    if ((dp = opendir(argv[1])) == NULL)
        err_sys("can't open %s", argv[1]);
    while ((dirp = readdir(dp)) != NULL)
        printf("%s\n", dirp->d_name);

    closedir(dp);
    exit(0);
}

终端执行

./fig1.3.out    ./

可以打印出当前目录下的文件/目录

其中argc表示运行时指定的参数的个数,argv数组保存参数的内容,如果没有参数,argv[0]为执行文件的文件名,argc=1。

我们先不关心DIR以及dirent结构的具体内容,仅观察其中的函数调用

opendir函数以一个目录名为参数,返回一个DIR类型的指针。

readdir函数以一个DIR类型的指针为参数,返回一个dirent类型的指针

dirp->d_name返回目录项的名字

整个函数模拟了ls命令 


Unbuffered I/O函数通常有:
open, read, write, lseek, 和close

#include "apue.h"

#define BUFFSIZE    4096

int
main(void)
{
    int     n;
    char    buf[BUFFSIZE];

    while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
        if (write(STDOUT_FILENO, buf, n) != n)
            err_sys("write error");
        if (n < 0)
            err_sys("read error");
        exit(0);
}

终端执行:

 ./fig1.4.out < infile > outfile

将infile中的文件作为fig1.4.out的输入,并将输出重定向至outfile文件
STDIN_FILENO和STDOUT_FILENO是在头文件<unistd.h>中定义的两个常数,通常取0和1,代表标准I/O的文件描述符

BUFFSIZE指定了缓冲区的大小为4096个字节

read函数将标准输入(终端)中的数据保存至缓冲区buf中,并返回读到的字节数,如果发生读错误,返回-1。当错误发生时,大多数的系统函数返回1,
write函数从缓冲区中取出n个字节后输出至屏幕。



Buffered I/O 函数:

Buffered I/O 可以避免我们去考虑BUFFSIZE的大小,以及简化了解决以行为输入的问题。

#include "apue.h"

int
main(void)
{
    int     c;

    while ((c = getc(stdin)) != EOF)
        if (putc(c, stdout) == EOF)
            err_sys("output error");

    if (ferror(stdin))
        err_sys("input error");

    exit(0);
}

getc函数一次从标准输入读1个字符,putc函数将字符c输出至标准输出。


进程:

getpid()函数返回当前进程的进程id

三个主要的进程操作函数分别是:fork,exec,waitpid。相关的使用方法如下:

#include "apue.h"
#include <sys/wait.h>

int
main(void)
{
    char    buf[MAXLINE];   /* from apue.h */
    pid_t   pid;
    int     status;

    printf("%% ");  /* print prompt (printf requires %% to print %) */
    while (fgets(buf, MAXLINE, stdin) != NULL) {
        if (buf[strlen(buf) - 1] == "\n")
            buf[strlen(buf) - 1] = 0; /* replace newline with null */

        if ((pid = fork()) < 0) {
            err_sys("fork error");
        } else if (pid == 0) {      /* child */
            execlp(buf, buf, (char *)0);
            err_ret("couldn't execute: %s", buf);
            exit(127);
        }

        /* parent */
        if ((pid = waitpid(pid, &status, 0)) < 0)
            err_sys("waitpid error");
        printf("%% ");
    }
    exit(0);
}

fgets函数从标准输入读取一行。

注意要将换行符改变成字符串终结符'\0'


int execlp(const char * file,const char * arg,...,(char *)0);

execlp函数会从PATH 环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……,最后一个参数必须用空指针(NULL)作结束。如果用常数0来表示一个空指针。


fork()函数产生一个当前进程的复制进程作为子进程

返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1


pid_t waitpid(pid_t pid,int * status,int options);

waitpid()会暂时停止目前进程的执行,直到有信号来到或子进程
结束。如果在调用 waitpid()时子进程已经结束,则 waitpid()会立即
返回子进程结束状态值。

参数pid为等待的子进程id,status接受子进程结束的状态值,返回值为子进程id

抱歉!评论已关闭.