0

I'm getting an undeclared identifier error for the i in word[i] in the last of the 'do-while' loop. (word[i]) was accepted previously in the for loop as it is defined in the get-string at the top of the code(not shown here). For some reason it is not recognised in the do-while loop outside of the 'for' loops. I have tried defining it again in various parts of the code even immediately outside and inside the 'do' but then error says the definition is overshadowed by the previous one in the 'get_string'. The 'do-while' loop needs to iterate at the same time as the two internal 'for' loops so both internal 'for' loops and the 'do while' loop need to access the same (word[i]). I would appreciate advice. I can add more original code if the question is unclear. I have edited to avoid spoilers.

I would like to use my existing code, if possible, rather than use someone else's, as I know the internal 'for' loop works perfectly as it was the one I used for Caesar.

   do   //loop to iterate through the letters in the key   
    {     

    for(int l=0; l<strlen(key); l++) //iterate over letters in key
        {
        int num=l;


        for(int i=0; i<strlen(word); i++) //iterates through key word entered by user
            {   

            if(isupper(word[i])) //if original characters are uppercase 
                {
                int cipher = (word[i] + num -65) % 26 + 65; 
                printf("%c", cipher);
                }

            (I REMOVED CODE HERE DUE SPOILERS)

            else    //all other types of characters
                {
                printf("%c", word[i]); 
                } 
            }
        }        
        printf("\n");

    }    

    while((word[i])<strlen(word));  

    }  

}

1

Variables in C are declared in block-scope. You can access all variables in current scope, and in scopes that contain the current scope (unless shadowed by variables of the same name declared in more inner scopes).

You would have to declare i in a scope that's above (in a hierarchical sense) the do..while loop, though some of your code makes little sense to me (innermost loop looks almost ok).

You have 1 do..while and 2 for loops, while you need only one loop over the text. Also, in (word[i])<strlen(word), you try to compare a character to a string length. Characters might be very short integers, but here there's no relation to the string length.

In Vigenère ciphers, you'd keep two indices, one for the plaintext, and one for the key. The one for the key is advanced only when you use the current key character for encryption, if you just copy a non-letter, it stays the same.

Example structure:

int keylen = strlen(key);
int textlen = strlen(plaintext);
for (int textpos = 0, keypos = 0; textpos < textlen; textpos++)
{
    if (isalpha(plaintext[textpos])) {
        // encrypt plaintext[textpos] using key[keypos]
        // and print encrypted letter

        // keypos increment version 1:
        keypos++;
        if (keypos >= keylen)
        {
            keypos = 0;
        }
        // version 2:
        keypos = (keypos + 1) % keylen;
        // (use only one of the two)
    }
    else
    {
        // print plaintext[textpos]
    }
}
Only textpos is incremented automatically, keypos instead is incremented on encrypting a letter. Another version would be keypos++; without a wrap-around in incrementing, and encrypt using key[keypos % keylen] instead of key[keypos].

  • It's hard to see what I'm trying to do when I can't post the whole code. I've had someone come in and edit most of the question out in the past. I understand that's how the Vigenere cipher works. The inner 'for' loop here is to iterate through the plaintext word and the outer 'for' loop is to iterate through the key word. I added the do-while to iterate again if necessary for cases were the plaintext word is longer than the key. E.g. if the key is 'cat' and plaintext word entered by the user is 'encyclopedia' then cat would have to be iterated over repeatedly. How else could this be done? – Android1 Mar 15 '17 at 13:55
  • Use one loop over the plain text. Have your key's index initially at 0, increment it on letter encryption, and wrap it around on reaching the key length (or always use it % the key length). One loop. – Blauelf Mar 15 '17 at 13:57
  • How do I 'wrap it around' without using an extra loop? I also don't know what you mean by 'use it % the key length'. Can you explain it more simply. I'm fairly new to all this. Are you talking about modifying the for loop with the key? I don't know how to create a for loop which iterates then wraps around and does this again. – Android1 Mar 15 '17 at 14:19
  • Added some code of the structure, minus the encryption itself (be sure to use the key characters, not the index, and account for case of both plaintext and key character, which can come in any combination) – Blauelf Mar 15 '17 at 15:13
  • My internal for loop was the one I used for Caesar which passed check50 and worked perfectly. The instructions were that we should use our Caesar Cipher as the bones for the Vigenere. I'll study up on how to use modulus in this equation and incorporate your code. Thanks – Android1 Mar 15 '17 at 16:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .