简体   繁体   中英

c: How can I read from a file and save value to another file caeser cipher program?

Here is my problem:

The Caesar Cipher technique is one of the earliest and simplest methods of encryption technique. It's simply a type of substitution cipher, ie, each letter of a given text is replaced by a letter some fixed number of positions down the alphabet. For example with a shift of 1, A would be replaced by B, B would become C, and so on. The method is apparently named after Julius Caesar, who apparently used it to communicate with his officials. Thus to cipher a given text we need an integer value, known as a shift which indicates the number of position each letter of the text has been moved down. The encryption can be represented using modular arithmetic by first transforming the letters into numbers, according to the scheme, A = 0, B = 1,…, Z = 25. Encryption of a letter by a shift n can be described mathematically as.

 E_n(x)=(x+n)mod\ 26 (Encryption Phase with shift n) D_n(x)=(xn)mod\ 26 (Decryption Phase with shift n)

Write an algorithm and implement a program in c to read the data from a file(called "test.txt"), transform the data according to the discussion in and aftwerward save it in another file(called "final.txt")

Here is my code but I can't find out what to do

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

char data[50], temp; int key, count;

void
getmessage()
{
    // printf("Enter a String:\t");
    // scanf("%[^\n]s", data);

    FILE *file_pointer;
    char buffer[30], c;

    file_pointer = fopen("test.txt", "r");
    printf("----reading the file----\n");
    fgets(buffer, 50, file_pointer);
    data[50] = buffer;
    printf("%s\n", buffer);

#if 0
    printf("----read and parse data----\n");
    file_pointer = fopen("test.txt", "r");  // reset the pointer
    char str1[10], str2[2], str3[20], str4[2];

    fscanf(file_pointer, "%s %s %s %s", str1, str2, str3, str4);
    printf("Read String1 |%s|\n", str1);
    printf("Read String2 |%s|\n", str2);
    printf("Read String3 |%s|\n", str3);
    printf("Read String4 |%s|\n", str4);
#endif

}

void
key_input()
{
    printf("Enter a Key:\t");
    scanf("%d", &key);
}

void
caesar_cipher_encryption()
{
    for (count = 0; data[count] != '\0'; count++) {
        temp = data[count];
        if (temp >= 'a' && temp <= 'z') {
            temp = temp + key;
            if (temp > 'z') {
                temp = temp - 'z' + 'a' - 1;
            }
            data[count] = temp;
        }
        else if (temp >= 'A' && temp <= 'Z') {
            temp = temp + key;
            if (temp > 'Z') {
                temp = temp - 'Z' + 'A' - 1;
            }
            data[count] = temp;
        }
    }
    printf("\nEncrypted Message:\t%s\n", data);
}

void
caesar_cipher_decryption()
{
    for (count = 0; data[count] != '\0'; count++) {
        temp = data[count];
        if (temp >= 'a' && temp <= 'z') {
            temp = temp - key;
            if (temp < 'a') {
                temp = temp + 'z' - 'a' + 1;
            }
            data[count] = temp;
        }
        else if (temp >= 'A' && temp <= 'Z') {
            temp = temp - key;
            if (temp < 'A') {
                temp = temp + 'Z' - 'A' + 1;
            }
            data[count] = temp;
        }
    }
    printf("\nDecrypted Message:\t%s\n", data);
}

int
main()
{
    int choice;

    getmessage();
    key_input();
    while (1) {
        printf("\n1. Encryption\n2. Decryption\n3. Exit\n");
        printf("\nEnter You Choice:\t");
        scanf("%d", &choice);
        switch (choice) {
        case 1:
            caesar_cipher_encryption();
            break;
        case 2:
            caesar_cipher_decryption();
            break;
        case 3:
            exit(0);
        default:
            printf("\nPlease select a correct option:\n");
        }
    }
    printf("\n");
    return 0;
}

Your input of the data string in get_message is wrong:

  1. It has UB (undefined behavior) because it writes past the end of buffer .
  2. Also, buffer is never copied to [the global variable] data , so data always has garbage.
  3. Better to input directly to data [and eliminate buffer ]. This seems okay because the other functions use the global data
  4. We should increase the size of the buffers to allow for longer phrases

Both the encryption and decryption functions replicate the code depending upon whether the character is upper or lower case. We should create two functions to centralize the transformations (passing limits as arguments).

The actual encryption/description algorithms don't match [AFAICT during testing].

Here's some refactored code. It is annotated and I've used cpp conditionals to show old vs. new code:

#if 0
// old code
#else
// new code
#endif

#if 1
// new code
#endif

Note that this code could be further cleaned up but I didn't want to get further afield of the existing code (eg change functions to accept buffer pointers as parameters, etc.):

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

// NOTE/BUG: data must be [at least] the same size as buffer in getmessage
// NOTE/BUG: temp should be function scoped
#if 0
char data[50], temp;
#else
#define BUFMAX      1000
char data[BUFMAX];
#endif
int key, count;

void
getmessage()
{
    // printf("Enter a String:\t");
    // scanf("%[^\n]s", data);

    FILE *file_pointer;
// NOTE/BUG: the buffer is local and we can input directly into temp
#if 0
    char buffer[30], c;
#endif

// NOTE/BUG: there is no corresponding fclose for this
    file_pointer = fopen("test.txt", "r");

    printf("----reading the file----\n");

// NOTE/BUG: this causes UB (undefined behavior) because we store past the
// end of buffer
// NOTE/BUG: buffer never gets into data
// NOTE/BUG: newline is not stripped properly
#if 0
    fgets(buffer, 50, file_pointer);
    data[50] = buffer;
    printf("%s\n", buffer);
// NOTE/FIX: we can input directly into data
#else
    if (file_pointer == NULL) {
        perror("test.txt");
        exit(1);
    }
    fgets(data, sizeof(data), file_pointer);
    data[strcspn(data,"\n")] = 0;
    fclose(file_pointer);
    printf("%s\n", data);
#endif

#if 0
    printf("----read and parse data----\n");
    file_pointer = fopen("test.txt", "r");  // reset the pointer
    char str1[10], str2[2], str3[20], str4[2];

    fscanf(file_pointer, "%s %s %s %s", str1, str2, str3, str4);
    printf("Read String1 |%s|\n", str1);
    printf("Read String2 |%s|\n", str2);
    printf("Read String3 |%s|\n", str3);
    printf("Read String4 |%s|\n", str4);
#endif

}

void
key_input()
{
    printf("Enter a Key:\t");
    scanf("%d", &key);
}

int
encrypt(int chr,int lo,int hi)
{

    if ((chr >= lo) && (chr <= hi)) {
        chr += key;
        if (chr > hi) {
            chr -= hi;
            chr += lo;
            chr -= 1;
        }
    }
    else
        chr = 0;

    return chr;
}

int
decrypt(int chr,int lo,int hi)
{

    if ((chr >= lo) && (chr <= hi)) {
        chr -= key;
        if (chr < lo) {
            chr = chr - lo;
            chr += hi;
            chr += 1;
        }
    }
    else
        chr = 0;

    return chr;
}

void
caesar_cipher_encryption()
{
    int temp;
    int code;

    for (count = 0; data[count] != '\0'; count++) {
        temp = data[count];

        code = encrypt(temp,'a','z');
        if (code) {
            data[count] = code;
            continue;
        }

        code = encrypt(temp,'A','Z');
        if (code) {
            data[count] = code;
            continue;
        }
    }

    printf("\nEncrypted Message:\t%s\n", data);
}

void
caesar_cipher_decryption()
{
    int temp;
    int code;

    for (count = 0; data[count] != '\0'; count++) {
        temp = data[count];

        code = decrypt(temp,'a','z');
        if (code) {
            data[count] = code;
            continue;
        }

        code = decrypt(temp,'A','Z');
        if (code) {
            data[count] = code;
            continue;
        }
    }

    printf("\nDecrypted Message:\t%s\n", data);
}

int
main()
{
    int choice;

    getmessage();
    key_input();
    while (1) {
        printf("\n1. Encryption\n2. Decryption\n3. Exit\n");
        printf("\nEnter You Choice:\t");
        scanf("%d", &choice);
        switch (choice) {
        case 1:
            caesar_cipher_encryption();
            break;
        case 2:
            caesar_cipher_decryption();
            break;
        case 3:
            exit(0);
        default:
            printf("\nPlease select a correct option:\n");
        }
    }
    printf("\n");
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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