The task is to encrypt the sentence: " My hovercraft is full of eels." I missed the exercise class due to other duties ;) Anyway i came to an result made of sniplets i found on the internet and a bit of experimenting. it goes as follows:
#include <stdio.h>
int main ()
{
int i=0;
char str[]="My hovercraft is full of eels.";
char c;
while (str[i]) //While String is true (Still characters left)
{
if (str[i]!='z') //if character is NOT "z" shift character by one
{
(c=str[i]+1);
}
else {
(c=str[i]='a'); //if character equals "z" then the output is "a"
}
printf("%c" ,c); // Shows encrypted string
i++;
}
return 0;
}
My problem is i dont know what i really did. Could someone explain my code? :D
First i introduce the integer i which is =0 then a string of characters and the variable c which is a character as well. while there are character left in the string add 1 if it is not equal to z otherwise c equals a. so z = a but i honestly dont know why it needs i++ which i copied from a far more complex caesars code. so thats it.
while (str[i]) //While String is true (Still characters left)
This is a very common C idiom, but it's actually a tricky piece of code. i
is your index into the string. When i
is 0, str[i]
is the first character of the string (i.e. "first character plus zero characters"). When i
is 1, it's the second character of the string ("first character plus one character").
A "character" in C is just a number. So the letter "A" happens to be 65. Your string is:
char str[]="My hovercraft is full of eels.";
So this is really an array of numbers. What's not obvious is that C automatically appends a zero to the end of the string. So this is really just a convenience for:
char str[] = { 'M', 'y', ' ', 'h', ... 'l', 's', '.', '\0' };
That last \0
is called NUL
(or sometimes "null"). It's a character (a "letter"). It just happens to be the character with the value zero. And it marks the end of a string. This "array of byte-sized characters, followed by a NUL
" is incredibly common in C, and is widely called a cstring ("C string"), even when it shows up in other languages. This is not the only way to represent strings, but it is by far the most common in C, and it's what you get when you use the "..."
syntax.
So each character is a number, and the last character is zero. Now we use another common C idiom: zero is false, all other values are true. So while (str[i])
is equivalent to:
while (str[i] != 0)
or even more precisely:
while (str[i] != '\0')
Which is an insanely long-winded way of saying "until i
refers to the end of the string."
(Don't despair. The rest is surprising simple compared to that first line. But that first line is incredibly common in C, so you need to understand all the little things that are happening.)
if (str[i]!='z') //if character is NOT "z" shift character by one
Easy-peasy. If the current character we're looking at isn't a z
... "We're looking at" is defined by i
.
(c=str[i]+1);
Don't know why there are parentheses here. That's kind of unusual. But the point is to just take the character we're looking at, and add one to the numeric representation of it, and assign that to c
. Since both ASCII and UTF8 (two very common ways to encode strings) put the Latin alphabet in order, "a+1" is "b".
Note that this is not implementing a proper Caesar cipher. In a traditional Caesar cipher with offset 1, "Z" would shift to "A". In this cipher, "Z" will shift to "[". But I'm being pedantic. It's just worth understanding that this cipher has some surprising corner cases. For instance, it will encode both z
and backtick `
as a
, so it can technically lose information and cannot be reversed over arbitrary ASCII input (it's completely broken for UTF8 input, so we won't even discuss that here). Not a big deal, but as programmers, corner cases are our lives, so it's good to know what inputs this works for and what inputs it does not work for.
(c=str[i]='a'); //if character equals "z" then the output is "a"
This line is almost certainly a bug. The parentheses are weird again, but not a problem. The problem with this line of code is that it modifies str
, which the previous code did not. Almost certainly this code should read:
c = 'a';
When the current character is z
, the output should be a
.
printf("%c" ,c); // Shows encrypted string
The comment here is a little misleading. It should say "shows encrypted character."
i++;
And we move our index forward one character before starting the process again. i++
is just a C-ism for i = i + 1
. (It's slightly more complicated than that when it appears inside of an expression, but in this case, you could exactly replace it with i = i + 1
.)
return 0;
And in the Unix style (which C is deeply entwined with), main()
returns zero to mean "no error."