0

这是一个任务(不是我的,而是我正在帮助的人,如果这很重要的话),但应该编写一个模仿 unix ar 命令的程序。我非常接近使用 stat() 函数将文件信息写入标题,但是在写入文件时我得到的是 @^ 而不是空格。

这是一个输出示例

1-s.txt2^@^@^@^@^@^@^@^@10月30日星期三 149972^@14601^@100640^@^@101^@^@^@^@^@^@^@ and it should be 1-s.txt2/ Wed Oct 30 149972 14601 100640 101

除了日期应该是一个unix时间戳之外,任何帮助也将不胜感激。

谢谢!!!

struct ar_hdr headerstruct;

void setfileinfo(const struct stat *sfileinfo){

sprintf(headerstruct.ar_name, "%s", global_argv[3]);

sprintf(headerstruct.ar_date, "%s", ctime(&sfileinfo->st_mtime));

sprintf(headerstruct.ar_uid, "%ld", (long)sfileinfo->st_uid);

sprintf(headerstruct.ar_gid, "%ld", (long) sfileinfo->st_gid);

sprintf(headerstruct.ar_mode, "%lo",(unsigned long)sfileinfo->st_mode);

sprintf(headerstruct.ar_size, "%lld",(long long)sfileinfo->st_size);

char filemag[2] = "`\n";

int fd;
fd = open(global_argv[2], O_RDWR);
lseek(fd, 0, SEEK_END);
write(fd, headerstruct.ar_name, 16);
write(fd, headerstruct.ar_date, 12);
write(fd, headerstruct.ar_uid, 6);
write(fd, headerstruct.ar_gid, 6);
write(fd, headerstruct.ar_mode, 8);
write(fd, headerstruct.ar_size, 10);
write(fd, filemag ,2);

return;

}
4

4 回答 4

2

您正在编写一堆垃圾,因为无论字符串有多长,您都在编写 16 个(或其他)字符。

尝试更改为:

write(fd, headerstruct.ar_name, strlen(headerstruct.ar_name));

等等。在它固定长度字段的情况下,从长度中减去 1,write()如果你想要它作为分隔符,请故意使用空格字符。

于 2013-10-30T23:34:59.073 回答
2

由于ar标头需要空格填充,您可以考虑使用空格预填充memset数据结构或特定成员。例如:

    memset(&headerstruct, ' ', sizeof(headerstruct));

此外,如果您想避免在标头中使用以 null 结尾的字符串,您应该使用类似memcpyor strncpy(具有适当长度)而不是sprintf,因为sprintf将在字符串末尾插入一个零字节。

于 2013-10-30T23:46:12.893 回答
1

你没有得到@^, but ^@,这是一个空字节。也就是说,来自全局变量 headerstruct 的内存被初始化为零。

我只会使用fprintf(3)而不是sprintf(3). 结构中的中间存储不会给您带来额外的好处。

于 2013-10-30T23:44:10.727 回答
1

如果您希望这些字符数组中未使用的字符为空白,则需要在此处放置空白。

一种方法是

size_t ansize;

ansize = sizeof(headerstruct.ar_name);
snprintf(headerstruct.ar_name, ansize, "%-*.*s", (int)ansize, (int)ansize, global_argv[3]);
于 2013-10-30T23:52:06.800 回答