3

我编写了一个 C 程序来使用 libarchive 从 tar 存档中提取文件。

我想从此档案中提取一个文件并将其打印到标准输出。 但我得到了额外的字符。这是垃圾,但它来自另一个文件(可能在存档中与它相邻。)我希望输出以</html>.

这是读取此 tar 文件的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "archive.h"
#include "archive_entry.h"


int main (int argc, const char * argv[]) 
{
    struct archive *a;
    struct archive_entry *entry;
    int r;
    int64_t entry_size;
    a = archive_read_new();
    archive_read_support_compression_none(a);
    archive_read_support_format_tar(a);
    r = archive_read_open_filename(a, "0000.tar", 1024);
    if (r != ARCHIVE_OK)
    {
        printf("archive not found");
    }
    else 
    {
        while (archive_read_next_header(a, &entry) == ARCHIVE_OK) 
        {
            const char *currentFile = archive_entry_pathname(entry);
            char *fileContents;
            entry_size = archive_entry_size(entry); //get the size of the file
            fileContents = malloc(entry_size); //alloc enough for string - from my testing I see that this is how many bytes tar and ls report from command line
            archive_read_data(a, fileContents, entry_size); //read data into fileContents string for the HTML file size
            if(strcmp(currentFile, "vendar-definition.html") == 0)
            {
                printf("file name = %s, size = %lld\n", currentFile, entry_size);
                printf("%s\n\n", fileContents); //this output over-reads chars from another file in this tar file
            }           
            free(fileContents); //free the C string because I malloc'd
        }
    }
    printf("exit");
    return 0;
}

在 mac os X 10.6.3 上编译的libarchive 2.8.3 。gcc 4.2 x86_64

ls -l vendar-definition.html给我1921文件大小。等等显示tar tfv 0000.tar | grep vendar-definition.html。因此报告说明文件大小的 C 输出。对我来说,这似乎是正确的。

我可以看到为什么我的输出不符合预期的两种可能性:

  1. 我犯了初学者的错误或
  2. 存档文件中的多字节字符与它有关。
4

2 回答 2

2

我可能是非常错误的,但这看起来不像一个以 null 结尾的字符串(我认为不会archive_read_data处理这个问题)。附加一个 NULL 字符或查看这个并告诉我们它是如何进行的。

于 2010-05-21T15:07:39.460 回答
1

我怀疑您没有阅读太多字符,而只是打印了太多。

您正在使用说明%s符 to输出文件内容printf,它期望输入是以 null 结尾的字符串。存档中文件的内容可能不是以空值结尾的,并且可能在中间包含任意空值。

尝试像这样输出:

fwrite(fileContents, sizeof(char), entry_size, stdout);
于 2010-05-21T15:07:10.403 回答