如何将以下内容转换为char []?

时间:2013-07-22 15:54:52

标签: c string operating-system

我使用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;
}

2 个答案:

答案 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文档中查找字段宽度修饰符。

更好的是,不要将数据存储为字符串,而是直接从原始数据的(副本)打印出来。