Thread: problem with modulo

  1. #1
    Registered User
    Join Date
    Aug 2012
    Posts
    11

    problem with modulo

    Code:
    #include <stdio.h>
    #include <cs50.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    int
    main(int argc, char *argv[])
    {
        // check number of arguments
        if (argc != 2)
        {
            printf("You must enter 1 argument. You also cannot enter more than 1.\n");
            return 1;
        }
        
        // check if alpabetical
        int keyLenght = strlen(argv[1]);
        char *key = argv[1];
        for (int i = 0; i < keyLenght; i++)
        {
            if ( !isalpha( key[i] ) )
            {    
                printf("Argument must be alpabetical only. \n");
                return 1; 
            }
        }
        
        // User enters message
        printf("Enter your secret message: ");
        char *inputTxt = GetString();
        
        // encrypt and print cypher
        printf("Secret message encrypted : ");
        int inputLenght = strlen(inputTxt);
        for (int i = 0; i < inputLenght; i++) 
        {   
            // transform key string into int from 1 to 26
            int finalKey = key[i];
            if ( isupper(finalKey) )
                finalKey = finalKey - 65;
            if ( islower(finalKey) )
                finalKey = finalKey - 97;
            finalKey = finalKey % keyLenght; 
                
            // encrypts capital letters
            if (inputTxt[i] >= 65 && inputTxt[i] <= 90)
            {    
                // transforms char from ascii to 1 to 26 and adds key
                char cypherChar = inputTxt[i] - 65 + finalKey;
                // modulo 1 to 26 number and transforms back to ascii
                cypherChar = (cypherChar % 26) + 65;
                // prints the character
                printf("%c", cypherChar);        
            }
            // encrypts small letters
            else if (inputTxt[i] >= 97 && inputTxt[i] <= 122)
            {    
                // transforms char from ascii to 1 to 26 and adds key
                char cypherChar = inputTxt[i] - 97 + finalKey;
                // modulo 1 to 26 number and transforms back to ascii
                cypherChar = (cypherChar % 26) + 97;
                // prints the character
                printf("%c", cypherChar);        
            }
            else
                // prints the character
                printf("%c", inputTxt[i]);   
        }
        
        // end of program
        printf("\n");
        return 0;
    }
    There's a problem with the modulo on the finalKey variable. I never took math so I don't understand modulo very well but I think I need it to accomplish the desired result.

    What the program is supposed to do:

    Take the each letter of the key variable, transform it into its number from 0 to 25, then take the secret message and move each of the letters up in the alphabetical order by the number of one of the characters in key. When the key string runs out of character, it should go back to its first character.

    What happens when I run my program:

    jharvard@appliance (~/Desktop/cs50 projects): ./vigenere bbaa
    Enter your secret message: aaaaaa
    Secret message encrypted : bbaaad

    Conclusion

    I *think* everything is working except for this part:

    Code:
            // transform key string into int from 1 to 26
            int finalKey = key[i];
            if ( isupper(finalKey) )
                finalKey = finalKey - 65;
            if ( islower(finalKey) )
                finalKey = finalKey - 97;
            finalKey = finalKey % keyLenght;
    If anyone can tell me what the problem is and maybe a simple way to understand modulo that would be awesome.

  2. #2
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    First thing I noticed is that you have spelled "length" and "alphabetical" wrong.
    Does GetString use malloc? Can you show that function so that we can check it is correct?

    Don't use magic numbers like 65 and 97, 90 or 122. Instead use things like 'a', 'A', or 'z'. Once you fix that up it will be easier to reason about whether it is correct or not, so I'll wait until you've done that before I look further.

    Oh and make sure you say what the expected output is, as well as the actual output.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    cypherChar % 26 is just the remainder when dividing cypherChar by 26.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    An example:

    Code:
    #include <stdio.h>
    
    int main(void) {
       int i;
       for(i=0;i<10;i++) {
          printf("Number %d modulo 10 is: %d\n",i,i % 10);
    
       printf("\nHit enter to continue");
       getchar();
       return 0;
    }
    Run the above snippet and see if it helps you better understand the modulo (remainder) operator.

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    I'd change Adak's example so the printf() line reads
    Code:
        fprintf("Number %d modulo 10 is: %d\n",i+16, (i+16) % 10);
    The value 16 is arbitrary, but as long as it is a positive value, it will show the concept better. Possibly also increase the number of times around the loop from 10 to 29, to really make it clear. (Again, I picked the 29 at random).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #6
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Code:
    // encrypt and print cypher
    printf("Secret message encrypted : ");
    int inputLenght = strlen(inputTxt);
    for (int i = 0; i < inputLenght; i++) 
    {   
        // transform key string into int from 1 to 26
        int finalKey = key[i];
        if ( isupper(finalKey) )
        finalKey = finalKey - 65;
        if ( islower(finalKey) )
        finalKey = finalKey - 97;
        finalKey = finalKey % keyLenght;
    I think you want to encrypt every letter of the message by adding a corresponding letter from the key like:
    Code:
    key: abc
    
    message: Secret message
    add key: abcabcabcabcab
    result:  Tgfsgw ohtudhg
    Correct?

    Then you have to use the modulo operator on the index variable (i) and not on "finalKey". "i" is the index for the message string and will probably be bigger than the length of your key string.

    Bye, Andreas

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Modulo 12
    By jack_carver in forum C Programming
    Replies: 12
    Last Post: 04-10-2010, 04:11 AM
  2. Problem with modulo calculation
    By manutdfan in forum C Programming
    Replies: 6
    Last Post: 01-12-2009, 03:37 PM
  3. modulo 2 modulus
    By breik in forum C Programming
    Replies: 5
    Last Post: 03-24-2006, 02:30 PM
  4. Modulo
    By Lurker in forum C Programming
    Replies: 3
    Last Post: 03-24-2003, 09:17 AM
  5. Modulus/Modulo?
    By Shadow12345 in forum C++ Programming
    Replies: 6
    Last Post: 03-13-2002, 11:29 PM