1
#include <stdio.h>

int main()

#include <stdio.h>

int main()

{
    char msg[31] = {'\0'};
    char encrypted[31] = {'\0'};
    int key;


    printf("Please enter a message under 30 characters: ");
    fgets(msg, 31, stdin);

    printf("Please enter an encryption key: ");
    scanf("%d", &key);

    int i = 0;

    while (msg[i] && ('a' <= msg[i] <= 'z' || 'A' < msg[i] < 'Z'))
{
    encrypted[i] = (msg[i] + key);
    i++;
}

    printf("%s\n", msg);
    printf("%d\n", key);
    printf("%s\n", encrypted);

}

Okay i've got my code to increment the characters but i don't know how to make it ignore special characters and spaces. Also how do i use % to loop back to 'a' and 'A'?

Thank you.

Haris
  • 12,120
  • 6
  • 43
  • 70
NeXtMaN_786
  • 661
  • 2
  • 12
  • 23

3 Answers3

0

scanf and fgets seem fine in this situation the way you've used them.

In C, a string is just an array of characters. So, you access each element using a for loop and array indexing:

for (int i = 0; i < strlen(str); i++) {
  char thisChar = str[i];
  //Do the processing for each character
}

You can perform arithmetic on thisChar as necessary, but be careful not to exceed 255. You might want to put a check on key to ensure it doesn't get too big.

devrobf
  • 6,973
  • 2
  • 32
  • 46
  • 1
    It would be a better idea to precompute `strlen`, because, as I understand, `strlen` is `O(n)` EDIT: http://stackoverflow.com/questions/4132849/strlen-in-c-and-c-how-does-it-work – Ryan Amos Jan 28 '13 at 22:33
  • 1
    Fair comment, although I don't think speed is a priority here - Premature Optimisation and all that :) – devrobf Jan 28 '13 at 22:36
  • True enough. The code probably won't be slow, but if it is, the O(n^2) will be the cause... however, n < 31, so no big deal. – Ryan Amos Jan 28 '13 at 22:38
0
  1. You just need a simple for loop:

    for (int i = 0; i < 31; i++)
    {
        // operate on msg[i]
    }
    

    If you didn't know the length of the string to begin with, you might prefer a while loop that detects the null terminator:

    int i = 0;
    while (msg[i])
    {
        // operate on msg[i]
        i++;
    }
    
  2. Your fgets and scanf are probably fine, but personally, I would be consistent when reading input, and fgets for it all. Then you can sscanf to get key out later.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
  • That would work, too. It's just a bit non-idiomatic for a beginner, I think. – Carl Norum Jan 28 '13 at 22:36
  • Okay i've done that and i've got it to increment. But now theres another problem. How do i make it so that spaces and special characters don't increment. Also how do i get letters to loop back to 'a'. I've tried this: while (msg[i]) { if ('a' <= msg[i] <= 'z' || 'A' < msg[i] < 'Z') { encrypted[i] = (msg[i] + key); i++; } else { i++; – NeXtMaN_786 Jan 28 '13 at 23:01
  • The comparison operators don't stack up like that. You need `if ((msg[i] >= 'a') && (msg[i] <= 'z'))`, etc. etc. – Carl Norum Jan 28 '13 at 23:23
0

Getting a string from scanf:

char msg[31];
scanf("%30s", msg);

OR (less efficient, because you have to fill the array with 0s first)

char msg[31] = { 0 };
scanf("%30c", msg);

Iterating a string is as easy a for loop (be sure to use c99 or c11)

int len = strlen(msg);
for(int i = 0; i < len; i++) {
    char current = msg[i];
    //do something
    msg[i] = current;
}

"Encrypting" (i.e. ciphering) a character require a few steps

  1. Determine if we have an uppercase character, lowercase character, or non-alphabetic character
  2. Determine the position in the alphabet, if alphabetic.
  3. Update the position, using the modulus operator (%)
  4. Correct the position, if alphabetic

I could give you the code here, but then you wouldn't learn anything from doing it yourself. Instead, I encourage you to implement the cipher based on the steps I provided above.

Note that you can do things like:

char c = 'C';
char e = 'E' + 2; 
char lower_c = 'C' - 'A' + 'a';
Ryan Amos
  • 5,422
  • 4
  • 36
  • 56
  • thanks, i've got the code to increment the key but now im stuck on using modulus to loop back to a or A and i also don't know how to get it not to increment special characters and spaces. I've done this and it still doesn't work. while (msg[i]) { if ('a' <= msg[i] <= 'z' || 'A' < msg[i] < 'Z') { encrypted[i] = (msg[i] + key); i++; } else { i++; } } – NeXtMaN_786 Jan 28 '13 at 23:07
  • Try handling uppercase separate from lowercase. Also, `'a' <= msg[i] <= 'z'` isn't valid, but `'a' <= msg[i] && 'z' >= msg[i]` does. The reason you need to handle upper & lower separately is because uppercase have a value of about 30 more than lowercase. – Ryan Amos Jan 29 '13 at 02:37
  • @NeXtMaN_786 Also, you'll need to get the character between 0-25, add your key, then modulus, then get it back to a character. That's why you have to handle upper and lower case separately -- because you subtract different numbers to get them 0-25. – Ryan Amos Jan 29 '13 at 05:45