使用sscanf()函数来解析归档文件

时间:2015-10-23 01:42:55

标签: c

我正在编写一个程序来读取存档文件的标题,并使用sscanf()函数打印出它的重要数据。效果应该类似于ls shell命令。

示例存档文件:

!<arch>
file1/          1445559998  17099 88    33188   4         `
one
file2/          1445485080  17099 88    33188   5         `
Two.

第一行是一个8-char&#34;魔术字符串&#34;将文件标识为存档,第二行和第四行是标题,第三行和第五行是文件的内容。

标题通过使用右边距(空格)保持正好60个字节的长度(在&#39;是\ n char之后)。

来自ar.h:

#include <ar.h>
struct  ar_hdr       /* file member header */
 {
     char    ar_name[16];    /* '/' terminated file member name */
     char    ar_date[12];    /* file member date */
     char    ar_uid[6]       /* file member user identification */
     char    ar_gid[6]       /* file member group identification */
     char    ar_mode[8]      /* file member mode (octal) */
     char    ar_size[10];    /* file member size */
     char    ar_fmag[2];     /* header trailer string */
 };

现在我的代码。对于初学者,我希望能够打印出文件名:

file1
file2

我有这个代码来完成这个,除了我遇到了分段错误。

void parseArc(int fd_ar)    // fd of archive
{
        struct stat statbuf;
        fstat(fd_ar, &statbuf);

        char buf[statbuf.st_blksize];
        char *filename;
        int where;

        where = 8;

        while (where <= statbuf.st_size)
        {
                lseek(fd_ar, where, SEEK_SET);

                read(fd_ar, buf, 60);    // read the header

                sscanf(buf, "%s/          ", filename);

                printf("%s\n", filename);

                where = where+60+4;    // 60 for header length, 4 for file1 length
        }
}

一个明显的错误是最后一行的+4。理想情况下,这将被替换为包含文件长度的变量,这是通过正确使用sscanf()获得的。

我的主要问题是,为什么我会遇到段错误?我假设它在sscanf()函数上。我已经阅读了函数API,但我无法弄清楚我是如何滥用它的。 THX。

1 个答案:

答案 0 :(得分:3)

您从未初始化指针filename。因此sscanf正在尝试将从buf提取的字符串写入内存中的随机位置。因此,段错误。

filename设为数组,或致电malloc为其分配一些空间。

sscanf%s本身一起使用通常很危险,因为您可能会得到一个超过为字符串分配的空间的长字符串。这是一个缓冲区溢出,当您的客户开始使用时,它将导致需要紧急安全补丁。请改用%42s之类的内容。

(您可能认为自己是安全的,因为buf最多只有60个字节,但是如果它没有被终止会怎样?)

大多数编译器应该能够注意到您正在使用filename未初始化,并警告您。 (gcc -Wall会。)你的编译器中是否有警告?如果不是,请羞辱你。如果是,并且你收到了警告但却忽略了它,那就羞辱你了。