我使用strcpy和sprintf将一些值(例如长十进制)转换为ar_hdr struct的属性。当我打开存档时,它看起来像:
0000000 2 - s . t x t \0 \0 \0 \0 \0 \0 \0 \0 \0
0000020 1 3 7 4 0 8 7 6 3 2 \0 \0 5 0 1 \0
0000040 \0 \0 2 0 \0 \0 \0 \0 1 0 0 6 4 4 \0 \0
0000060 8 2 \0 \0 \0 \0 \0 \0 \0 \0 ` \n 2 2 2 2
0000100 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
*
0000140 2 2 2 2 \n 2 2 2 2 2 2 2 2 2 2 2
0000160 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0000200 2 2 2 2 2 2 2 2 2 2 2 2 2 \n
0000216
我想在“”(只是一个空格)时替换所有“\ 0”。有人能给我一个如何解决这个问题的提示吗?谢谢。 以下是我写的一些代码。
int main (int argc, char **argv)
{
char *archive = argv[1];
char *read_file = argv[2];
int in_fd;
int out_fd;
//char title[] = ARMAG; //constant define in ar.h
char buf[BLOCKSIZE];
char tmpBuf[BLOCKSIZE];
int num_read;
int num_written;
struct stat stat_file;
struct ar_hdr my_ar;
FILE *fp;
//open read_file (i.e., text file)
if (stat(read_file, &stat_file) == -1){
perror("Error in Stat");
exit(-1);
}
//open read file
in_fd = open(read_file, O_RDONLY);
if (in_fd == -1) {
perror("Canot open/create output file");
exit(-1);
}
//assign file info to struct dhr (my_ar)
//all my_ar attributes = char []
strcpy(my_ar.ar_name, read_file);
sprintf(my_ar.ar_date, "%ld", stat_file.st_mtimespec.tv_sec);
sprintf(my_ar.ar_uid, "%ld", (long)stat_file.st_uid);
sprintf(my_ar.ar_gid, "%ld", (long)stat_file.st_gid);
sprintf(my_ar.ar_mode, "%o", stat_file.st_mode);
sprintf(my_ar.ar_size, "%lld", stat_file.st_size);
strcpy(my_ar.ar_fmag, ARFMAG);
//0666 - open archive
out_fd = open(archive, O_CREAT | O_WRONLY | O_APPEND, 0666);
if (out_fd == -1) {
perror("Canot open/create output file");
exit(-1);
}
//write my_ar struct to archive
//num_written = write(out_fd, title, sizeof(title));
off_t curpos = lseek(out_fd, SEEK_CUR, 0); //get current position
if(curpos == 0) { //if it is at beginning, it must be a new file
num_written = write(out_fd, ARMAG, SARMAG);
num_written = write(out_fd, &my_ar, sizeof(my_ar));
}
else
{
num_written = write(out_fd, &my_ar, sizeof(my_ar));
}
//add the file content to archive
off_t in_fd_pos = lseek(in_fd, 0, SEEK_CUR);
while ((num_read = read(in_fd, buf, BLOCKSIZE)) >0) {
num_written = write(out_fd, buf, BLOCKSIZE);
if (num_written != num_read) {
perror("Error writing file");
exit(-1);
}
}
return 0;
}
答案 0 :(得分:1)
根据sprintf()
:
成功返回后,这些函数返回的数量 打印的字符(不包括用于结束输出的
null
字节 字符串)。
因此,'\0'
为每个成员字段添加了一个sprintf()
。每个成员字段的其余'\0'
s可能是由my_ar
的初始化值引起的。您可以运行expt
来查看初始my_ar
是否属于non-null
值。
sprintf()
返回有关写入字符数的值。因此,您可以使用该字段用空格替换'\0'
。
答案 1 :(得分:1)
您的代码似乎将一些文本写入结构中的某些固定长度字符串,但您没有提供struct ar_hdr
的定义,因此我无法确定。
然后将整个结构转储到一个文件中,但由于每个字符串都是以空字符结尾的,并且因为字符串之间存在未初始化的值(也恰好包含空字符),所以你会得到不需要的输出中的垃圾。
我建议您不只将内存转储到文件中。做好工作要好得多。如何将数据写入文件如下:
FILE *out_file = fdopen(out_fd); /* or use fopen in the first place */
fprintf("%s %s %s %s %s %s", my_ar.ar_name, my_ar.ar_date, my_ar.ar_uid,
my_ar.ar_gid, my_ar.ar_mode, my_ar.ar_size);
如果仍需要固定长度的字符串,则在printf文档中查找字段宽度修饰符。
更好的是,不要将数据存储为字符串,而是直接从原始数据的(副本)打印出来。