我在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));
}
}
}
答案 0 :(得分:4)
由于您提供了输入文件的内容,我几乎可以肯定主要的问题是您在加密文本上使用了面向字符串的string.h和stdio.h函数。
考虑一下:您的输入文件主要由数字组成,您的问题密码也包含数字。与自身进行异或的字符将产生一个零字节,大多数处理字符串的C函数都会将其视为字符串的结尾!
编辑:
处理这个问题的方法是在每个缓冲区附带一个整数,表示其中的字符数,然后坚持使用内存区域操作函数,如memcpy,memcmp等。你还应该避免使用* puts ()和* gets()用于文件I / O,因为它们也是面向字符串的。
编辑2:
基本上,您应该将输入文件视为包含未知内容的二进制文件,而不是文本文件。这将使您的代码更加强大和通用,但这也意味着您不能使用任何str *()函数。