简体   繁体   English

文件中印有多余的字符

[英]Extra Characters printed in the file

I have made a program to encrypt and decrypt a message using a vigenere cipher. 我制作了一个程序,使用vigenere密码对消息进行加密和解密。

While encrypting or decrypting the text, some extra garbage values are printed in it. 在加密或解密文本时,其中会打印一些额外的垃圾值。

It takes the input from a file named input.txt and outputs to output.txt , you have to write the message in the input.txt file and while running you have to give a key (a word with alphanumeric characters). 它从名为input.txt的文件中获取输入,并输出到output.txt ,您必须在input.txt文件中编写消息,并且在运行时必须提供一个键(一个包含字母数字字符的单词)。

Why is this is happening? 为什么会这样呢?

The code is as follows: 代码如下:

#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;

    }
}

When you are allocating and copying here 当您在此处分配和复制时

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);

you've allocated sz bytes in buffer, and copied sz bytes, but you didn't leave room for the null terminator. 您已经在缓冲区中分配了sz字节,并复制了sz字节,但是您没有为null终止符留出空间。 Hence, when you check strlen(buffer) and encrypt later, you're going off into memory you didn't allocate. 因此,当您检查strlen(buffer)并在以后加密时,您将进入未分配的内存。

To fix this, either you have to allocate one extra byte for the '\\0' , or you copy over one less and tack on the '\\0' at the end. 为了解决这个问题,或者你在为分配一个额外的字节'\\0' ,或者您复制一个都不能少和粘性的'\\0'结尾。

Wrong length calculation. 长度计算错误。

As mention by @Dennis Meng, the strlen(buffer) likely (*1) goes off past the end of your allocated buffer. 如@Dennis Meng所述,strlen(buffer) 可能 (* 1)超出了分配的缓冲区的末尾。 Your malloc() is fine. 您的malloc()很好。 The recommended solution is different. 推荐的解决方案是不同的。 Rather than tacking on a NUL char, change for 2 for loops 无需添加NUL字符,而是将for循环更改为2

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

to

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

Not only will this fix the problem, it will run faster as you are no longer performing strlen(buffer) sz times. 这不仅可以解决问题,而且由于不再执行strlen(buffer) sz次,因此运行速度更快。

*1 It would not go that far had your file contained a NUL character. * 1如果文件中包含NUL字符,那将不会太远。 If it does go past the end of buffer , where things stop is UB. 如果确实超过了buffer的末尾,则UB停止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM