2

我正在开发一个简单的“类焦油”归档 C 程序。它通过在文本文件中写入所有文件、目录和文件内容来工作,并且可以以相同的方式提取它们(它创建空文件,然后用存档内容填充它们)。

当我必须归档文本文件或 PDF 时,它运行良好。

对于 MP3 等音频文件,在提取结束时,我在 shell 上有这些行:

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

我不知道为什么程序在 shell 上写这个,为什么它只对音轨这样做。通过执行它们,我注意到只有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");
    }

}

我的存档有 3 个部分:%LIST%、%DIRS% 和 %CONTENT%。

crea_file读取 %LIST% 部分并在当前目录中创建空文件。
TrovaInizioFine读取 %CONTENT% 部分并保存 2 个索引:一个在文件内容的开头,一个在其结尾。
scrivifile用归档内容填充空文件。

4

1 回答 1

2

没有任何代码可看,这很难。

不过,你说的一件事让我怀疑有问题:

它通过在文本文件中写入所有文件、目录和文件内容来工作

在大多数情况下,您不能将任意二进制数据视为文本。C 库可能会进行行尾转换,这将破坏二进制数据。您必须对任意数据使用二进制文件,或者注意“保护”数据,以便它真正能够作为文本处理。

去二进制。

于 2013-05-10T08:20:52.313 回答