2

私は単純な「tar のような」アーカイブ C プログラムを開発しています。すべてのファイル、ディレクトリ、およびファイルの内容をテキスト ファイルに書き込むことで機能し、同じ方法でそれらを抽出できます (空のファイルを作成し、アーカイブ コンテンツで埋めます)。

テキスト ファイルや PDF をアーカイブする必要がある場合は、うまく機能します。

MP3 などのオーディオ ファイルでは、抽出の最後に、シェルに次の行があります。

1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;
2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;
2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c;1;1;112;112;
1;0x1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c;1;1;112;112;1;0x1;2c1;2c1;2c1;
2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;
2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c

プログラムがこれをシェルに書き込む理由と、オーディオトラックでのみこれを行う理由がわかりません。1;それらを実行することで、コマンドだけが実行され、2c1;コマンドが不明であることに気付きました。

理由を教えていただけますか?

これは、部分を抽出するために私が書いたコードです:

void crea_file(FILE *f)                                             // crea i file estratti dall'archivio
{
    int contatore = 0;
    char x[4096];
    bool listTrovata = false;
    while (fscanf(f, " %s", x) == 1) {
        if(strcmp(x, "%LIST%")==0 && listTrovata==false)
        {
            listTrovata= true;
            puts("trovato il primo \n");
            continue;
        }
        else if (strcmp(x, "%LIST%")==0 && listTrovata)
        {
            long position;
            position = ftell(f);
            printf("trovato il secondo \n");
            printf("LIST trovato alla posizione %ld", position);
            fseek(f, 0, SEEK_END);
            break;
        }
        else if (listTrovata)
        {
            contatore++;
            char* file;                         // stringa contenente il percorso da aprire (verrà creato in seguito)
            file = collega(getcwd(NULL, 0), x);
            creat(file, PERMS);
            printf("sto cercando l'inizio e la fine di content, passando un contatore %d \n", contatore);
            trovaInizioFine(contatore);
            printf("ora scrivo il file trovato");
            scriviFile(file);
            //inserisco funzione che parte da inizio e scrive carattere per carattere nel file destinazione. se la posizione di ftell è uguale a fine, allora esci.
        }
    }
    printf("esco \n");
}

void trovaInizioFine(int cont)                                      // trova il carattere di inizio e di fine del file nella sezione %CONTENT%
{
    FILE* contenuto;
    char * path;
    char x[4096];
    int i =1;
    path = collegaSlash(getcwd(NULL, 0), nome);

    contenuto = fopen(path, "r");
    while (fscanf(contenuto, "%s", x) == 1) 
    {
        if(strcmp(x, "%CONTENT%")==0 && i == ((cont*2)-1) )
        {
            inizio = ftell(contenuto);
            puts("trovato il primo \n");
            //puts(x);
            printf("CONTENT trovato alla posizione %d \n", inizio);
            i++;
        }
        else if(strcmp(x, "%CONTENT%")==0 && i == ((cont*2)) )
        {
            fine = ftell(contenuto);
            daleggere = fine-9;
            puts("trovato il primo \n");
            printf("CONTENT trovato alla posizione %d \n", fine);
            break;
            i++;
        }
        else if(strcmp(x, "%CONTENT%")==0)
        {
            i++;    
        }


        printf("giro numero %d \n", i);
    }

    printf("esco da trova Inizio File  \n");
    fclose(contenuto);

}

void scriviFile(const char * arrivo)                                //scrive i file creati in precedenza
{
    FILE * partenza;
    FILE * target;
    int c;
    int spazio = 'a';
    int i = 0;
    int pos;
    char * path;
    path = collegaSlash(getcwd(NULL, 0), nome);
    partenza = fopen(path, "r");
    fseek(partenza, inizio, SEEK_SET);
    target = fopen(arrivo, "w");                                            //apro il file
    if (target) {                                                               //se è aperto
        while ((c = fgetc(partenza)) != EOF && ftell(partenza)<=fine-10) {                                  //e il carattere preso non eccede la fine del file
            fputc(c, target);
            fputc(c, stdout);
            pos = ftell(partenza);
            if(pos==fine)
            {
                break;
            }
                                                                            //scrivo lo stesso carattere in out (file in uscita)
        }                                                                   //

        fclose(target);                                                     //chiudo il file
        fclose(partenza);
    } 
    else 
    {
        printf("errore di scrittura del file \n");
    }

}

私のアーカイブには、%LIST%、%DIRS%、%CONTENT% の 3 つのセクションがあります。

crea_file%LIST% セクションを読み取り、現在のディレクトリに空のファイルを作成します。
TrovaInizioFine%CONTENT% セクションを読み取り、2 つのインデックスを保存します。1 つはファイル コンテンツの先頭にあり、もう 1 つは末尾にあります。
scrivifile空のファイルをアーカイブ コンテンツで埋めます。

4

1 に答える 1

2

見るコードがなければ、これは非常に困難です。

それでも、あなたが言うことの1つは、私に問題を疑わせます:

すべてのファイル、ディレクトリ、およびファイルの内容をテキストファイルに書き込むことで機能します

ほとんどの場合、任意のバイナリ データをテキストとして扱うことはできません。C ライブラリは、バイナリ データを破壊する行末変換を行う可能性があります。任意のデータにはバイナリファイルを使用するか、データを "保護" して、テキストとして扱われても存続するように注意する必要があります。

バイナリに進みます。

于 2013-05-10T08:20:52.313 に答える