1

我用 C 语言编写了一个程序,该程序使用每个字符中的 xor 操作加密结构的元素。

当我使用包含非数字字符的密码时,代码运行正常。但如果密码包含数字字符,则结构的元素不能完全打印。这是文件的内容(文件名是'input'):

500
0 25
5
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25

这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//This structure stores the file data
typedef struct arqc{
    char* npontos;
    char* carta;
    char* ordem;
    char** matriz;
}Arqc;

int learq( Arqc* fp, FILE* arq );
char criptografa( char ch, char chave );
void decriptografa( Arqc* fp, char* chave, int tam_matriz );

int main()
{
    FILE* arq = fopen("input.txt","r");
    Arqc* fp;
    int i;
    int tam;
    char* chave = "adr";
    fp = (Arqc*) malloc(sizeof(Arqc));
    if( fp == NULL )
        exit(-1);
    tam = learq( fp, arq );
    decriptografa( fp, chave, tam );
    puts( fp->npontos);
    puts( fp->carta);
    puts( fp->ordem);
    for( i = 0; i < tam ; i++){
        puts( *(fp->matriz + i));
    }

    decriptografa( fp, chave, tam );
    puts( fp->npontos);
    puts( fp->carta);
    puts( fp->ordem);
    for( i = 0; i < tam ; i++){
        puts( *(fp->matriz + i));
    }

    for( i = 0; i < tam ; i++){
        free( *(fp->matriz + i));
    }
    free(fp->npontos);
    free(fp->carta);
    free(fp->ordem);
    free(fp);
    fclose( arq );
    return 0;
}

//read the file and stores it in a struct
int learq( Arqc* fp, FILE* arq ){
    int i = 0;
    int tam;
    int n;
    int sair = 1;
    char aux[101];//stores a string read from the file
    /* *************************************************** */
    //this stretch every element of the struct will be filled
    // with the characters in each line of the file
    fgets( aux, 10, arq);
    tam = strlen( aux );
    fp->npontos = (char*) malloc(tam*sizeof(char));
    strncpy( fp->npontos, aux, tam - 1);
    *(fp->npontos + tam - 1) = '\0';
    fgets( aux, 10, arq);
    tam = strlen( aux );
    fp->carta = (char*) malloc(tam*sizeof(char));
    strncpy( fp->carta, aux, tam - 1);
    *(fp->carta + tam - 1) = '\0';
    fgets( aux, 10, arq);
    tam = strlen( aux );
    fp->ordem = (char*) malloc(tam*sizeof(char));
    strncpy( fp->ordem, aux, tam - 1);
    *(fp->ordem + tam - 1) = '\0';
    /* ************************************************** */
    //read here is the character corresponding to the order of the matrix
    //that is converted to the corresponding integer
    n = atoi(fp->ordem);
    //llocating the number of rows of the matrix
    fp->matriz = ( char**) malloc( n*sizeof(char*));
    while( sair ){
        //while the file is not closed, the struct will receive the file data
        if( fgets( aux, 101, arq) != NULL){
            tam = strlen( aux );
            *(fp->matriz + i) = (char*) malloc(tam*sizeof(char));
            strncpy( *(fp->matriz + i), aux, tam - 1);
            *(*(fp->matriz + i) + tam - 1) = '\0';
            i++;
        }
        else
            sair = 0;
    }
 //retorna a dimensão da matriz
 return n;
}

//criptografa cada caractere ch com um caractere chave
char criptografa( char ch, char chave ){
     ch = ( ch&~chave)|(~ch&chave);
     return ch;
}

//decrypts the file that was stored in fp using 'chave' to decrypt
void decriptografa( Arqc* fp, char* chave, int tam_matriz ){
    char aux[101];
    int i, j;
    int n;
    int tchave;
    strcpy( aux, fp->npontos);
    n = strlen( aux );
    tchave = strlen( chave );
    for( i = 0; i < n; i++){
        //decrypts each character read from the struct using the 'chave' characters
        *(fp->npontos + i) = criptografa( *(fp->npontos + i), *(chave + i%tchave));
    }
    strcpy( aux, fp->carta);
    n = strlen( aux );
    for( i = 0; i < n; i++){
        //decrypts each character read from the struct using the 'chave' characters
        *(fp->carta + i) = criptografa( *(fp->carta + i), *(chave + i%tchave));
    }
    strcpy( aux, fp->ordem);
    n = strlen( aux );
    for( i = 0; i < n; i++){
        //decrypts each character read from the struct using the 'chave' characters
        *(fp->ordem + i) = criptografa( *(fp->ordem + i), *(chave + i%tchave));
    }
    for( i = 0; i < tam_matriz; i++){
        strcpy( aux, *(fp->matriz + i));
        n = strlen( aux );
        for( j = 0; j < n; j++){
            //decrypts each character read from the struct using the 'chave' characters
            *(*(fp->matriz + i) + j) = criptografa( *(*(fp->matriz + i) + j), *(chave + i%tchave));
            printf("%c\n", *(*(fp->matriz + i) + j));
        }
    }

}
4

1 回答 1

4

由于您提供了输入文件的内容,我几乎可以肯定主要问题是您在加密文本上使用了面向字符串的 string.h 和 stdio.h 函数。

想一想:您的输入文件主要由数字组成,而您的问题密码也包含数字。与自身异或的字符将产生一个零字节,大多数处理字符串的 C 函数将其视为字符串的结尾!

编辑:

处理这个问题的方法是给每个缓冲区加上一个整数,表示其中的字符数,然后坚持使用内存区域操作函数,如 memcpy、memcmp 等。你还应该避免 *puts() 和*gets() 用于文件 I/O,因为它们也是面向字符串的。

编辑2:

基本上,您应该将输入文件视为内容未知的二进制文件,而不是文本文件。这将使您的代码更加健壮和通用,但这也意味着您不能使用任何 str*() 函数。

于 2010-12-04T21:48:24.753 回答