对于家庭作业,我在C中编写了一些代码,用于打印存储在achive文件中的文件的权限和文件名。我的代码编译,但由于某种原因,第二个文件的名称将在新行中返回。
以下是我的输出在终端中的样子:
rw-r--r-- 501/20 1-s.txt
rw-r--r-- 501/20
2-s.txt
(empty blank line here)
这就是我想要输出的样子:
rw-r--r-- 501/20 1-s.txt
rw-r--r-- 501/20 2-s.txt
(no empty blank line here)
有人可以查看我的代码并提供一些有关如何修复代码的提示吗?我怀疑它与我阅读和选择文件名的方式有关(使用my_ar.ar_name
),但我无法弄清楚如何修复它。谢谢你的时间。
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/utsname.h>
#include <ctype.h>
#include <string.h>
#include <ar.h>
int main (int argc, char **argv)
{
FILE *fp;
size_t readNum;
long long tot_file_size, cur_file_size;
struct stat fileStat;
struct ar_hdr my_ar;
//open the archive file (e.g., hw.a)
fp = fopen(argv[1], "r");
if (fp == NULL)
{
perror("Error opening the file\n");
exit(-1);
}
//size of the archive file
fseek(fp, 0, SEEK_END);
tot_file_size =ftell(fp);
rewind(fp);
//read data into struct
fseek(fp, strlen(ARMAG), SEEK_SET);
file_size_cnt = 0;
while (ftell(fp) < tot_file_size - 1)
{
readNum = fread(&my_ar, sizeof(my_ar), 1, fp);
if (stat(argv[1], &fileStat) == -1) {
perror("stat");
exit(EXIT_FAILURE);
}
if ((fileStat.st_mode & S_IFMT) == S_IFREG)
{
printf( (fileStat.st_mode & S_IRUSR) ? "r" : "-");
printf( (fileStat.st_mode & S_IWUSR) ? "w" : "-");
printf( (fileStat.st_mode & S_IXUSR) ? "x" : "-");
printf( (fileStat.st_mode & S_IRGRP) ? "r" : "-");
printf( (fileStat.st_mode & S_IWGRP) ? "w" : "-");
printf( (fileStat.st_mode & S_IXGRP) ? "x" : "-");
printf( (fileStat.st_mode & S_IROTH) ? "r" : "-");
printf( (fileStat.st_mode & S_IWOTH) ? "w" : "-");
printf( (fileStat.st_mode & S_IXOTH) ? "x" : "-");
printf("%.*s", 15, my_ar.ar_name);
printf("\n");
}
cur_file_size = atoll(my_ar.ar_size);
if (fseek(fp, cur_file_size, SEEK_CUR) != 0)
{
perror("You have an error.\n");
exit(-1);
}
}
//printf("\n");
fclose(fp);
return 0;
}
答案 0 :(得分:0)
您不希望打印新行吗?所以不要打印它!
删除它:
printf("\n");
它位于代码的末尾。
修改强>
我认为你不想完全删除它,但你想在上次以外的任何时间打印它。
if (ftell(fp) != tot_file_size - 1) {
printf("\n");
}
编辑V1.1
在改进之后,我在linux mint 13下运行了你的代码。这是我的输出:
rw-r--r--a.txt/
rw-r--r--b.txt/
这是你想要的格式,不是吗?
答案 1 :(得分:0)
有很多问题。
OP有if (stat(argv[1], &fileStat) == -1) ...
,好奇地反复询问“文件的文件名”的文件状态,而不是my_ar.ar_name
中的文件名。因此,将显示相同的文件统计信息。
printf("%.*s", 15, my_ar.ar_name)
的首次使用给出了“501/20 1-s.txt”。这看起来像一个不寻常的文件名。 ar_name
字段为“如果文件成员名称适合,则ar_name字段直接包含名称,并以斜杠(/)结尾并在右侧填充空格。如果成员的名称不适合,则为ar_name在下面描述的归档字符串表中包含斜杠(/)后跟名称偏移量的十进制表示。“因此,/
的存在意味着您还需要做更多工作来提取文件名。也可能是字段不 NUL字节终止。 OP需要在struct ar_hdr
上阅读。尝试:http://www.lehman.cuny.edu/cgi-bin/man-cgi?ar.h+3
在此代码中错误地提取的文件名可能包含也可能不包含令人惊讶的字节。我确信这就是你在第二行输出中看到一个意外的行尾的原因。测试可打印ASCII char
的文件名是谨慎的。 isprint()