凯撒密码(C):从文本文件中读取

时间:2013-10-20 21:11:55

标签: c arrays file-io encryption

我正在使用Caesar密码,我的代码几乎已经完成,但我遇到了从文本文件(txt)中读取句子,将其存储在数组中,解码并将其再次存储在文本文件中的问题。 / p>

到目前为止,我已经设法打开文本文件,逐行读取,并在控制台上显示。

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

void encode(char message[], int shift)
{
    int i;
    FILE *pout;
    pout = fopen("OutputTrial_encode.txt", "w");
    if (pout == NULL)
    {
        printf("File could not be opened for writing!\n");
        exit(1);
    }

    for(i=0;i<strlen(message);i++) 
    { 
        if (!isalpha(message[i]))
            continue;                           
        // checking for upper case 
        if(isupper(message[i]))
            message[i]=((message[i]-'A') + shift) % 26 + 'A'; 
        else 
            //checking for lower case 
            if(islower(message[i]))  
                message[i]=((message[i]-'a') + shift) % 26 + 'a'; 
    }

    printf("\n%s\n", message);
    fprintf(pout, "%s\n", message);
    if (fclose(pout) != 0)
        printf("Error in closing file!\n");
}

void decode(char message[], int shift)
{
    int i;
    FILE *pout;

    pout = fopen("OutputTrial_decode.txt", "w");
    if (pout == NULL)
    {
        printf("File could not be opened for writing!\n");
        exit(1);
    }

    for(i=0;i<strlen(message);i++) 
    { 
        if (!isalpha(message[i]))
            continue;                           
        // checking for upper case 
        if(isupper(message[i]))
            message[i]=((message[i]-'A') + (26-shift)) % 26 + 'A'; 
        else 
            //checking for lower case
            if(islower(message[i]))  
                message[i]=((message[i]-'a') + (26-shift)) % 26 + 'a'; 
    }

    printf("\n%s\n", message);
    fprintf(pout, "%s\n", message); 
    if (fclose(pout) != 0)
        printf("Error in closing file!\n");
}

void decode2(char word[], int shift)
{
int i;
FILE *pout;
//printf("Enter shift amount (1-25): ");
//scanf("%d", &shift);
pout = fopen("Output_Textfile.txt", "w");
if (pout == NULL)
{
printf("File could not be opened for writing!\n");
exit(1);
}

for(i=0;i<strlen(word);i++) 
{ 
if (!isalpha(word[i]))
continue;                           
// checking for upper case 
if(isupper(word[i]))
word[i]=((word[i]-'A') + (26-shift)) % 26 + 'A'; 
else 
//checking for lower case
if(islower(word[i]))     
word[i]=((word[i]-'a') + (26-shift)) % 26 + 'a'; 
}

printf("\n%s\n", word);
fprintf(pout, "%s\n", word); 
if (fclose(pout) != 0)
printf("Error in closing file!\n");
}


int main()
{ 
    int shift, choice1, choice2; 
    char message[80]; 

    printf("Selection: \n");
    printf("1. Encode/Decode\n");
    printf("2. Decode Textfile\n");
    printf("User input: ");
    scanf("%d", &choice1);
    fflush(stdin);

    if(choice1==1){
        printf("\nEnter message to be encrypted: "); 
        gets(message);
        printf("Enter shift amount (1-25): ");  
        scanf("%d", &shift); 
        //fflush(stdin);
        printf("\nSelection: \n");
        printf("1. Encode\n");
        printf("2. Decode\n");
        printf("User input: ");
        scanf("%d", &choice2);

        switch(choice2)
        {
        case 1:
            encode(message, shift);
            break;
        case 2:
            decode(message, shift);
            break;
        }
    }
    else {
        FILE *pin;
        char filename[50], word[100];
        int j=0;

        do{
            printf("\nEnter name of output file: ");
            scanf("%30s", filename);
            pin = fopen(filename, "r");
        } while(pin == NULL);

        if (pin == NULL)
        {
            printf("File could not be opened for reading!\n");
            exit(1);
        }
        while(!feof(pin))
        {

            word[j] = (char) fgetc(pin);  
            printf("%c", word[j]);
            if(feof(pin))
                break;
            j++;
        }
        printf("\nEnter shift amount (1-25): ");
        scanf("%d", &shift);
        decode2(word, shift);
        fclose(pin);
    }


    printf("\n");
    return 0; 
}

1 个答案:

答案 0 :(得分:1)

当您阅读消息时,看起来您没有终止C字符串。因此,在decode2中,函数strlen可能会返回一个虚假值,甚至可能会将其全部设置为崩溃。

在阅读周期中尝试:

    while(!feof(pin))
    {
        char c;
        c = (char) fgetc(pin);
        if (EOF == c) {
            break;
        }
        word[j] = c;
        printf("%c", word[j]);
        j++;
    }
    // We have already read all that we needed from the file, so let's
    // close it now and not have it linger. Also, after closing, its
    // file pointer can no longer be used; set it to NULL so that any
    // inadvertent usage may be easier to detect.
    fclose(pin); pin = NULL;

    // We have to mark string end. C ends strings with zeroes, and a zero
    // is a zero is a zero - we may indicate it in many equivalent ways:
    // '\x00'    the character zero
    // 0x0       zero in hexadecimal
    // 0         zero as decimal integer
    // To stress the point that this zero is part of a string, I use either
    // 0x0 or '\x00'. But word[j] = 0 works just as well; it's a taste.
    word[j] = '\x00';

即使输入文件末尾有额外的字符,我也得到了正确的结果。这是由于Jonathan Leffler指出的另一个问题:在这个循环中,EOF角色也被阅读并像消息角色一样对待,当然它本不应该。 (以上代码已更正)

由于您仅对字母字符使用凯撒密码,因此您可以使用fgets而不是一次只读一个字符。

    Selection:
    1. Encode/Decode
    2. Decode Textfile
    User input: 2

    Enter name of output file (Ctrl-C to quit): OutputTrial_encode.txt
    BUUBDL BU EBXO


    Enter shift amount (1-25): 1
    ATTACK AT DAWN