2013-08-20 2 views
0

Я создал программу для шифрования и расшифровки сообщения с использованием шифрования vigenere.Дополнительные символы, напечатанные в файле

При шифровании или расшифровке текста в нем печатаются дополнительные значения мусора.

Он принимает входные данные из файла с именем input.txt и выходов output.txt, вы должны написать сообщение в файле input.txt и во время работы вы должны дать ключ (слово с буквенно-цифровыми символами).

Почему это происходит?

Код выглядит следующим образом:

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



int Encrypt(char key[])   // CODE FOR ENCRYPTION 
{ 
    int sz = 0, i; 
    FILE *ifp, *ofp; 
    ifp = fopen("input.txt", "r"); 
    char *buffer; 
    char outputFilename[] = "output.txt"; 


    if (ifp == NULL) 
    { 
     fprintf(stderr, "Cant open input file\n"); 
     exit(1); 
    } 


    fseek(ifp, 0, SEEK_END); 
    sz = ftell(ifp); 

    // printf("%d",sz); 

    fseek(ifp, 0, SEEK_SET); 


    /* allocate memory for entire content */ 
    buffer = (char *)malloc(sizeof(char) * sz); 
    if (!buffer) 
     fclose(ifp), fputs("memory alloc fails", stderr), exit(1); 

    /* copy the file into the buffer */ 
    if (1 != fread(buffer, sz, 1, ifp)) 
     fclose(ifp), free(buffer), fputs("entire read fails", stderr), exit(1); 


    ofp = fopen(outputFilename, "w"); 

    if (ofp == NULL) 
    { 
     fprintf(stderr, "Can't open output file !\n"); 
    } 
    // fprintf(ofp,"%s",buffer); 

    int j = 0; 
    for (i = 0; i < strlen(buffer); i++) 
    { 
     if (j > strlen(key) - 1) 
      j = 0; 
     if (buffer[i] >= 65 && buffer[i] < 91) 
     { 

      int c = ((((buffer[i] - 65) + ((key[j] - 65) % 26))) % 26) + 65; 
      fprintf(ofp, "%c", c); 

     } 
     else if (buffer[i] >= 97 && buffer[i] < 123) 
     { 
      int c = ((((buffer[i] - 97) + ((key[j] - 65) % 26))) % 26) + 97; 

      fprintf(ofp, "%c", toupper(c)); 

     } 
     else 
     { 
      fprintf(ofp, "%c", buffer[i]); 
      continue; 
     } 
     j++; 
    } 
    printf("\n"); 

    fclose(ifp); 
    fclose(ofp); 

    return 0; 
} 

int Decrypt(char key[])   // CODE FOR DECRYPTION 
{ 

    int sz = 0, i; 
    FILE *ifp, *ofp; 
    ifp = fopen("output.txt", "r"); 
    char *buffer; 
    char outputFilename[] = "output2.txt"; 


    if (ifp == NULL) 
    { 
     fprintf(stderr, "Cant open input file\n"); 
     exit(1); 
    } 


    fseek(ifp, 0, SEEK_END); 
    sz = ftell(ifp); 

    // printf("%d",sz); 

    fseek(ifp, 0, SEEK_SET); 

    /* allocate memory for entire content */ 
    buffer = (char *)malloc(sizeof(char) * sz); 
    if (!buffer) 
     fclose(ifp), fputs("memory alloc fails", stderr), exit(1); 

    /* copy the file into the buffer */ 
    if (1 != fread(buffer, sz, 1, ifp)) 
     fclose(ifp), free(buffer), fputs("entire read fails", stderr), exit(1); 


    ofp = fopen(outputFilename, "w"); 

    if (ofp == NULL) 
    { 
     fprintf(stderr, "Can't open output file !\n"); 
    } 
    // fprintf(ofp,"%s",buffer); 

    int j = 0; 
    for (i = 0; i < strlen(buffer); i++) 
    { 
     if (j > strlen(key) - 1) 
      j = 0; 
     if (buffer[i] >= 65 && buffer[i] < 91) 
     { 
      if (buffer[i] > key[j]) 
      { 
       int c = 
        ((((buffer[i] - 65) - ((key[j] - 65) % 26))) % 26) + 65; 
       fprintf(ofp, "%c", tolower(c)); 
      } 
      else 
      { 
       int c = ((((buffer[i] - key[j]) + 26)) % 26) + 65; 
       fprintf(ofp, "%c", tolower(c)); 
      } 
     } 
     else if (buffer[i] >= 97 && buffer[i] < 123) 
     { 
      int c = ((((buffer[i] - 97) - ((key[j] - 65) % 26))) % 26) + 97; 

      fprintf(ofp, "%c", tolower(c)); 

     } 
     else 
     { 
      fprintf(ofp, "%c", buffer[i]); 
      continue; 
     } 
     j++; 
    } 
    printf("\n"); 

    fclose(ifp); 
    fclose(ofp); 

    return 0; 
} 

void main() 
{ 
    int ch; 
    char key[20]; 
    a:printf("0.Exit the Menu\n1.Encrypt\n2.Decrypt\n"); 
    printf("Enter your choice\n"); 
    scanf("%d", &ch); 


    switch (ch) 
    { 

    case 0: 
     printf("Goodbye\n"); 
     break; 

    case 1: 
     printf 
      ("-----------------------------Welcome to the encryption zone---------------------\n"); 
     printf("Enter the key to be used\n"); 
     scanf("%s", key); 

     Encrypt(key); 
     break; 

    case 2: 
     printf 
      ("-----------------------------Welcome to the decryption zone---------------------\n"); 
     printf("Enter the key to be used\n"); 
     scanf("%s", key); 

     Decrypt(key); 
     break; 

    default: 
     printf("Enter the correct choice\n"); 
     goto a; 
     break; 

    } 
} 
+2

shot-in-the-dark: вы забыли окончить нуль? –

+0

Не используйте 'goto' в этом случае, используйте циклы. –

+0

И вы действительно должны переключить место второго и третьего аргументов на 'fread' и' fwrite'. Второй - размер каждого элемента, а третий - количество элементов. Разумеется, вы также должны изменить проверку возвращаемого значения. –

ответ

3

При выделении и копировании здесь

buffer = (char *)malloc(sizeof(char) * sz); 
if (!buffer) 
    fclose(ifp), fputs("memory alloc fails", stderr), exit(1); 

/* copy the file into the buffer */ 
if (1 != fread(buffer, sz, 1, ifp)) 
    fclose(ifp), free(buffer), fputs("entire read fails", stderr), exit(1); 

вы выделили sz байт в буфере, и копируются sz байт, но вы не сделали оставить место для нулевого терминатора. Следовательно, когда вы проверяете strlen(buffer) и шифруете позже, вы уходите в память, которую вы не выделили.

Чтобы исправить это, вам нужно выделить один дополнительный байт для '\0', или вы скопируете более одного и наложите на '\0' в конце.

+0

Я обнаружил, что проблема не возникает в ubuntu (gcc-компилятор), но возникает при компиляции в кодовых блоках на окнах. –

+1

Дело в том, что после того, как вы забегаете в нераспределенную память, вы мгновенно попадаете в неопределенное поведение. Вы пытались запустить свою программу с помощью проверки памяти, например 'valgrind'? Если он возвращает какие-либо ошибки памяти, то это не значит, что у вас нет проблемы, это то, что вам повезло, и неопределенное поведение случается, чтобы не включать в себя крах, который один раз. –

0

Неверный расчет длины.

Как упоминает @Dennis Meng, strlen (buffer) Вероятно, (* 1) уходит за конец вашего выделенного буфера. Ваш malloc() в порядке. Рекомендуемое решение отличается. Вместо того, чтобы лавировать на гольца NUL, изменение 2 for петель

for (i = 0; i < strlen(buffer); i++) 

в

for (i = 0; i < sz; i++) 

Это не только решить эту проблему, она будет работать быстрее, так как вы больше не выполняя strlen(buffer)sz раз.

* 1 Не было бы так далеко, если бы ваш файл содержал символ NUL. Если он заканчивается в конце buffer, где остановка вещей - UB.

 Смежные вопросы

  • Нет связанных вопросов^_^