-2

我正在研究凯撒密码,我的代码几乎完成了,但是我在从文本文件 (txt) 中读取句子、将其存储在数组中、对其进行解码以及将其再次存储在文本文件中时遇到问题。

到目前为止,我已经成功地打开了文本文件,逐行读取它,并将其显示在控制台上。

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

1 回答 1

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而不是一次读取一个字符。

    选择:
    1.编码/解码
    2.解码文本文件
    用户输入:2

    输入输出文件的名称(Ctrl-C 退出):OutputTrial_encode.txt
    BUUBDL BU EBXO


    输入班次数量(1-25):1
    黎明攻击
于 2013-10-20T22:09:30.617 回答