【问题标题】:print out contents of archived files in C在 C 中打印出归档文件的内容
【发布时间】:2013-10-20 22:23:29
【问题描述】:

我在这里发布了同样的问题:

How to print the name of the files inside an archive file?

但这些答案不一定能解决问题。我有一个存档文件 week.a,我想打印出该存档中文件的名称,称为 mon.txt 和 fri.txt。

它应该像 ar -t 命令一样工作,只是我不能使用它。

我尝试过的: 我的第一次尝试是创建一个 for 循环并打印出参数,但后来我意识到该文件已经存档,所以这不起作用。 我的第二次尝试是查看 ar 的 print_contents 函数,如下所示:

static void
print_contents (bfd *abfd)
{
  size_t ncopied = 0;
  char *cbuf = (char *) xmalloc (BUFSIZE);
  struct stat buf;
  size_t size;
  if (bfd_stat_arch_elt (abfd, &buf) != 0)
    /* xgettext:c-format */
    fatal (_("internal stat error on %s"), bfd_get_filename (abfd));

  if (verbose)
    printf ("\n<%s>\n\n", bfd_get_filename (abfd));

  bfd_seek (abfd, (file_ptr) 0, SEEK_SET);

  size = buf.st_size;
  while (ncopied < size)
    {

      size_t nread;
      size_t tocopy = size - ncopied;
      if (tocopy > BUFSIZE)
    tocopy = BUFSIZE;

      nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
      if (nread != tocopy)
    /* xgettext:c-format */
    fatal (_("%s is not a valid archive"),
           bfd_get_filename (bfd_my_archive (abfd)));

      /* fwrite in mingw32 may return int instead of size_t. Cast the
     return value to size_t to avoid comparison between signed and
     unsigned values.  */
      if ((size_t) fwrite (cbuf, 1, nread, stdout) != nread)
    fatal ("stdout: %s", strerror (errno));
      ncopied += tocopy;
    }
  free (cbuf);
}

但是对于这条路线,我真的不知道很多代码的含义或作用(我对 C 非常陌生)。有人可以帮助理解这段代码,或者指出我编写程序的正确方向吗?谢谢。

【问题讨论】:

  • 这是哪里来的? (什么环境)
  • GNU binutils package ar.c,只是摘录。
  • ar en.wikipedia.org/wiki/Ar_(Unix) 上的维基百科页面有足够的文件格式信息,可以编写一个解析器来提取文件名。
  • 嘿,我也调查了。它并没有真正说明我可以使用或查看来理解的 C 代码,尤其是对于初学者而言。你能详细说明你为什么这么说吗?
  • 忘记 ar.c - 你不需要的东西太复杂了(你发布的代码对解决问题没有用)。专注于理解文件格式。请参阅@AndreasBombe 的评论。基于该写下伪代码来检查全局头,然后读取第一个文件头。然后写 C 来打印存档中第一个文件的名称。更新伪代码以跳过文件内容并循环读取文件头等,直到文件结束。边走边检查幻数,这样您就知道您正在从正确的地方阅读。见cplusplus.com/reference/cstdio

标签: c archive


【解决方案1】:

基于wikipedia.org/wiki/Ar_(Unix) 的格式,您的程序的基本形状将是:

fopen(filename)
fscanf 8 characters/* global header */
check header is "!<arch>" followed by LF
while not at end of file  /* check return value of fcanf below  */
    fscanf each item in file header
    print filename /* first 16 characters of file header */
    check magic number is 0x60 0x0A
    skip file size characters  /* file contents - can use fseek with origin = SEEK_CUR */

fclose(file)

有关所需功能的详细信息,请参阅C stdio library documentation 。或查看Wikipedia C file input/output

【讨论】:

  • 谢谢,这帮了我很大的忙,我从这里有了一个良好的开端。欣赏它。
  • 不要使用feof() 并且请不要向初学者建议。
  • @joop,我同意,已更正。其他人应该看到stackoverflow.com/questions/5431941/…
【解决方案2】:
int counting(FILE *f)
{  

    int count=0;
    rewind(f);

    struct ar_hdr myheader;

    fseek(f,8,SEEK_CUR);

    while(fread(&myheader,sizeof(struct ar_hdr),1,f)>0)
    {
        long test;

        test = atol(myheader.ar_size);
        fseek(f,test,SEEK_CUR);
        count++;
    }       
    printf("count is : %d\n",count);
    return count;
}

我编写的这段代码是为了计算存档中的文件数。你也可以使用它来打印其中的文件名

【讨论】:

    猜你喜欢
    • 2010-12-13
    • 1970-01-01
    • 2021-08-02
    • 2021-05-12
    • 2013-10-21
    • 1970-01-01
    • 2016-05-14
    • 2014-05-17
    • 2012-06-12
    相关资源
    最近更新 更多