3

strcpy と sprintf を使用して、いくつかの値 (長い 10 進数など) を ar_hdr 構造体の属性に変換しました。アーカイブを開くと、次のようになります。

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;
}
4

2 に答える 2

1

あなたのコードは、構造体内の固定長文字列にテキストを書き込んでいるように見えますが、 の定義を提供していないため、struct ar_hdr確信が持てません。

次に、構造体全体をファイルにダンプしますが、各文字列が nul で終了し、文字列間に初期化されていない値があるため (たまたま nul 文字が含まれている場合もあります)、不要なジャンクがファイルに含まれています。出力。

メモリをファイルにダンプするだけではないことをお勧めします。仕事をきちんとこなしたほうがずっといい。次のようにデータをファイルに書き込むのはどうですか:

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 ドキュメントでフィールド幅修飾子を調べてください。

さらに良いのは、データを文字列として保存するのではなく、元のデータ (のコピー) から直接出力することです。

于 2013-07-22T16:42:28.573 に答える