Shift Cipher program in C[need some help]

shednikshednik Member Posts: 2,005
Hello all,

I don't know who on this forum is well versed in C but I figured I'd throw this up there to help me figure out where i'm being a moron at :D. So the program is fairly simple takes some input and a key then encrypts/decrypts the text. So my issue is in the converChar function, since the assignment calls for using an ALPHA char rather than a number for 'k' I had to write something to convert say the letter 'A' to 1 and so on. Take a look if anyone has any insight would be much appreciated.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define  MAXCHARS  255
#define  MAXS    4

int convertChar(char *a);
void encrypt();
void decrypt();

int main()
{
    char response[MAXS],plaintext[MAXCHARS];
    
    printf("Shift Cipher Program\n\nWould you like to (E)ncrypt or (D)ecrypt a message or (Q)uit.  ");
    scanf("%s",response);
    
    while (response[0] != 'q' && response[0] != 'Q') {
          switch (response[0]) {
                 case 'e':
                 case 'E':
                      encrypt();
                      break;
                 case 'd':
                 case 'D':
                      decrypt();
                      break;
                 default:
                         printf("error: invalid command\n");
                         break;
          }//end of switch
    printf("Would you like to (E)ncrypt or (D)ecrypt a message or (Q)uit.  ");
    scanf("%s",response);
    }//end of while
    return 0;
}//end of main


void encrypt()
{
     int i=0,k;
     char msg[MAXCHARS],*letter;

     printf("Please enter the plain text to encrypt in all CAPS and press enter\n");
     scanf ("%s",msg);
     printf("Please enter the alpha key(k) you would like to use  ");
     scanf ("%s",letter);
     k = convertChar(letter);
     while (msg[i]!= '\0') {
           if ((msg[i]+k) > 'Z')
           {
              msg[i] = ((((msg[i]+k) - 'Z')-1) + 'A'); //wrap to the beginning
              }
           else
               msg[i] = (msg[i]+k);
               
           i++;
     }
     printf("\n%s", msg);
     }

void decrypt()
{
     int i=0,k;
     char msg[MAXCHARS],*letter;

     printf("Please enter the cipher text to decrypt in all CAPS and press enter\n");
     scanf ("%s",msg);
     printf("Please enter the alpha key(k) you would like to use  "); 
  
     scanf ("%s",letter);
     k = convertChar(letter);
     
      while (msg[i]!= '\0') {
          if ((msg[i]-k) < 'A'){
            
              msg[i] = ('Z' - (('A' - (msg[i]-k))-1)); } //wrap to the end.
           else {
           
               msg[i] = (msg[i]-k); }    
          i++;
     }
     printf ("%s\n",msg);
}                        

int convertChar(char *a)
{
    static char *letters[26] = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
    int i=0;
    
    while(i<26){
        if (strcmp(letters[i],a)){
            printf("%d",i);
            return (i+1); }
        else
            i++;
    }
    return 0;
}



I've done a few different setups and some bring me an error of passing a pointer to an integer but they all error at the same point when I initiate the converChar function.

PS I'm a fairly new programmer in C so it may be something stupid I missed.

TIA!!

Comments

  • hypnotoadhypnotoad Banned Posts: 915
    In your convertChar function, you're not taking upper or lower case in to account.

    Doesnt C allow you to do arithmetic on chars as if they were ints, so you can manupulate them after accounting for their ascii value? So ascii value of A is 65. A + 3 = D (for example?). A + K = something. If K > 26 then take K mod 26...yes?

    I'm rusty there.
  • shednikshednik Member Posts: 2,005
    Sorry forgot to mention that the input is always going to be in caps, I haven't added the checks for that as of yet. So thats why my array only lists the capital alphabet. I tried doing something like this but that ended up crashing still after entering the letter.
         printf("Please enter the alpha key(k) you would like to use  ");
         scanf ("%s",letter);
         k = atoi((letter-64));
    

    Here's how the output looks before crashing if it helps.
    Shift Cipher Program
    
    Would you like to (E)ncrypt or (D)ecrypt a message or (Q)uit.  E
    Please enter the plain text to encrypt in all CAPS and press enter
    SHEDNIKTEST
    Please enter the alpha key(k) you would like to use  F
    
  • hypnotoadhypnotoad Banned Posts: 915
    for (int i = 0; i<strlen(msg);i++)
    printf("%s", (int) (msg+k) % 26);

    Add the integer value of the character to k, find the remainder of it when divided by 26 (to allow wrapping), Type cast the output back to string so you get char instead of int output. I don't remember if using (int) is considered ANSI C or not.

    atoi won't work -- C - atoi, itoa, sprintf and sscanf - apparently it stops processing when it sees a letter and not a number. Crappy function :)

    HTH. I might be on the totally wrong path. Maybe a non-rusty C programmer can clean this idea up?

    Edit
    in the for loop, it might be i<strlen(msg)-1 ---- is there even a strlen in C? or is that C++?
  • tierstentiersten Member Posts: 4,505
    The letter variable in the encrypt and decrypt functions isn't being initialised.
  • tierstentiersten Member Posts: 4,505
    hypnotoad wrote: »
    in the for loop, it might be i<strlen(msg)-1 ---- is there even a strlen in C? or is that C++?
    strlen is part of the standard C library.
  • tierstentiersten Member Posts: 4,505
    A shorter convertChar:

    int convertChar(char *a)
    {
    if (isalpha(a[0])) {
    return toupper(a[0]) - 'A' + 1;
    }

    return 0;
    }
  • shednikshednik Member Posts: 2,005
    I did some more testing it looks like it doesn't like the way i'm trying to assign a value to letters when I prompt for the value of k.
  • tierstentiersten Member Posts: 4,505
    shednik wrote: »
    I did some more testing it looks like it doesn't like the way i'm trying to assign a value to letters when I prompt for the value of k.
    You haven't initialised letters. scanf is trying to store a string into letters which doesn't exist. Allocate some memory for it like you did with msg or use malloc etc...

    Change that and your program will work.
  • kimanydkimanyd Banned Posts: 103
    Hi, my name's Shednik, and I like to ask for advice and then ignore it icon_lol.gif
  • shednikshednik Member Posts: 2,005
    Hey imposter go find another forum to ***** :D...So I changed my code to this now for each of the crypt functions...the char convert works but the encrypt stopped.
    void encrypt()
    {
         int i=0,k=0;
         char msg[MAXCHARS];
         char letter[MAXS];
         printf("Please enter the plain text to encrypt in all CAPS and press enter\n");
         scanf ("%s",msg);
         printf("Please enter the alpha key(k) in CAPS you would like to use\n");
         scanf ("%s",letter);
         while (strcmp(letters[k],letter)!=1)
               k++;
         while (msg[i]!= '\0') {
               if ((msg[i]+k) > 'Z')
                  msg[i] = ((((msg[i]+k) - 'Z')-1) + 'A'); //wrap to the beginning
               else
                   msg[i] = (msg[i]+k);
                   
               i++;
         }
         printf("\n%s", msg);
         }
    
    It looks like its not saving my input into msg now...I can't win!
  • sidsanderssidsanders Member Posts: 217 ■■■□□□□□□□
    while (strcmp(letters[k],letter)!=1)
    letters is not in scope in encrypt, how can you get it to compile currently?
    GO TEAM VENTURE!!!!
  • shednikshednik Member Posts: 2,005
    sidsanders wrote: »
    while (strcmp(letters[k],letter)!=1)
    letters is not in scope in encrypt, how can you get it to compile currently?
    I made it a global var I just didn't include that part.
  • sidsanderssidsanders Member Posts: 217 ■■■□□□□□□□
    ok. i take it also then you added an uppercase conversion for letter (or just toupper on letter[0])?
    GO TEAM VENTURE!!!!
  • shednikshednik Member Posts: 2,005
    sidsanders wrote: »
    ok. i take it also then you added an uppercase conversion for letter (or just toupper on letter[0])?

    Not yet since it wasn't a requirement for the assignment...It looks like once I assign a value to letter it is clearing out what was saved in msg. any thoughts?
  • sidsanderssidsanders Member Posts: 217 ■■■□□□□□□□
    is msg now a global var as well? one prob you will have is if you dont convert the case, your program will core **** (at least based on the last provided code).
    GO TEAM VENTURE!!!!
  • shednikshednik Member Posts: 2,005
    Here's the current code I have made it works on the char swap to an int of 0-25 but it seems now that everything is fine until I run the strcmp on letter and letters. It works fine but for some reason it clears out the text i entered into msg any ideas? All the text will be entered in CAPS no matter what I'm not adding the converts or checks since the assignment isn't requiring it.
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #define  MAXCHARS  255
    #define  MAXS    4
    
    int csearch(char *l);
    void encrypt();
    void decrypt();
    char *letters[26] = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
    
    int main()
    {
        char response[MAXS],plaintext[MAXCHARS];
        
        printf("Shift Cipher Program\n\nWould you like to (E)ncrypt or (D)ecrypt a message or (Q)uit.  ");
        scanf("%s",response);
        
        while (response[0] != 'q' && response[0] != 'Q') {
              switch (response[0]) {
                     case 'e':
                     case 'E':
                          encrypt();
                          break;
                     case 'd':
                     case 'D':
                          decrypt();
                          break;
                     default:
                             printf("error: invalid command\n");
                             break;
              }//end of switch
        printf("Would you like to (E)ncrypt or (D)ecrypt a message or (Q)uit.  ");
        scanf("%s",response);
        }//end of while
        return 0;
    }//end of main
    
    
    void encrypt()
    {
         int i=0,k=0;
         char msg[MAXCHARS];
         char letter[MAXS];
         
         printf("Please enter the plain text to encrypt in all CAPS and press enter\n");
         scanf ("%s",msg);
        // printf("%s\n",msg);
         printf("Please enter the alpha key(k) in CAPS you would like to use\n");
         scanf ("%s",letter);
       //  printf("%s\n",msg);
         while (strcmp(letters[k],letter)!=1)
               k++;
       //  printf("%d %d\n",i,k);
       //  printf("%s\n",msg);
         while (msg[i]!= '\0') {
               if ((msg[i]+k) > 'Z')
                  msg[i] = ((((msg[i]+k) - 'Z')-1) + 'A'); //wrap to the beginning
               else
                   msg[i] = (msg[i]+k);
                   
               i++;
         }
         printf("\n%s", msg);
         }
    
    void decrypt()
    {
         int i=0,k=0;
         char msg[MAXCHARS];
         char letter[MAXS];
         printf("Please enter the ciper text to decrypt in all CAPS and press enter\n");
         scanf ("%s",msg);
         printf("Please enter the alpha key(k) in CAPS you would like to use\n");
         scanf ("%s",letter);
         while (strcmp(letters[k],letter)!=1)
               k++;
         while (msg[i]!= '\0') {
              if ((msg[i]-k) < 'A'){
                  msg[i] = ('Z' - (('A' - (msg[i]-k))-1)); } //wrap to the end.
               else {
               
                   msg[i] = (msg[i]-k); }    
              i++;
         }
         printf ("%s\n",msg);
    }                        
    
  • sidsanderssidsanders Member Posts: 217 ■■■□□□□□□□
    prob is in encrypt still right?

    some quick changes i tried:
    int x;
    x=strlen(msg);

    changed your while --> while (i<x) {
    changed the printf (cosmetic) --> printf("%s\n", msg);

    and then ran it:
    Shift Cipher Program

    Would you like to (E)ncrypt or (D)ecrypt a message or (Q)uit. e
    Please enter the plain text to encrypt in all CAPS and press enter
    ZZZZ
    Please enter the alpha key(k) in CAPS you would like to use
    C
    CCCC
    Would you like to (E)ncrypt or (D)ecrypt a message or (Q)uit. q
    GO TEAM VENTURE!!!!
  • shednikshednik Member Posts: 2,005
    Thanks for the help sidsanders, it ended up working for me when I made a few changes. I appreciate the help though from everyone. I'll be writing a few more of these throughout the semester will definitely be in need of help.
Sign In or Register to comment.