Strange unwanted three digit code printouts from caesar cipher - c

The cipher code actually works; it's just that I get some odd three digit codes separated with slashes too.
Any help would be greatly appreciated. Here's my code.
The codes look like this but have random numbers /354/233/645/810/236
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cs50.h"
int i, len;
string sentance, encrypted;
int k, argvLen;
int caesar (int k){
printf("Hi I'm Ceaser! What would you like me to cipher?\n");
sentance = GetString();
len = strlen(sentance);
char encrypted[len];
for (i=0; i<len; i++) {
if (sentance[i] >='a' && sentance[i] <='z') {
encrypted[i] = ((sentance[i] - 'a' + k) % 26) + 'a';
}
else if (sentance[i] >='A' && sentance[i] <='Z') {
encrypted[i] = ((sentance[i] - 'A' + k) % 26) + 'A';
}
else if (sentance[i] >=' ' && sentance[i] <= '#'){
encrypted[i] = sentance[i];
}
}
printf("%s", encrypted);
return 0;
};
int main (int argc, const char * argv[]) {
if (argc==2) {
k = atoi(argv[1]);
argvLen = strlen(argv[1]);
for (i=0; i<argvLen; i++){
if (isdigit(argv[1][i])){
caesar(k);
}
else {
printf("please enter a number for the key!");
return 1;
}
}
return 0;
}
};

You are not terminating the encrypted string properly.
You need:
To make sure you have room for the terminating character, by using char encrypted[len + 1];.
encrypted[len] = '\0'; after the loop.

Related

CS50 Caesar - Check50 won't validate my code

I know that this question have been asked before, but I still can't find the clue to the problem in my code.
My program works apparently fine, but I'm not able to pass the check50 test. From what I understand, the issue may be related to the fact that the null \0 is printed. But I don't know how to modify that. Could you please help me?
This is my code:
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
bool only_digits(string s);
char rotate(char c, int n);
int main(int argc, string argv[])
{
string h = argv[1];
if (argc != 2 || !only_digits(h) || h <= 0)
{printf("Usage: ./caesar key\n");
return 1;
}
else
{
int key = atoi(argv[1]);
string plaintext = get_string("plaintext: ");
int f = strlen(plaintext);
printf("ciphertext: ");
for(int q = 0; q < f; q++)
{
printf("%c", rotate(plaintext[q], key));
}
printf("\n");
}
return 0;
}
bool only_digits(string s )
{
for (int i = 0, n = strlen(s); i < n; i++)
{
char digit = s[i];
if (!isdigit(digit))
return false;
}
return true;
}
char rotate(char c, int n)
{
if(isupper(c) && (c != '\0'))
{
printf("%c", (((c - 65) + n) % 26) + 65);
}
else
if(islower(c) && (c != '\0'))
{
printf("%c", (((c - 97) + n) % 26) + 97);
}
else
printf("%c", c);
return 0;
}
This is a caption of check50's check:
check50
rotate always returns 0, so printf("%c", rotate(plaintext[q], key)); is causing the letters you output to be interspaced with NUL characters.
I would keep that printf, but change rotate to return the character instead of printing it.

segmentation fault on CS50 Caesar and debugging

Hey all I asked a question related to this code earlier and got a lot of helpful answers (I'm very green at coding). While I overcame my initial problem and corrected a few more mistakes I've run into another error that I can't seem to fix. I keep getting the Segmentation fault but I want it to prompt the user to give a second argument. Along with that when I do give the number, the code doesn't seem to actually encrypt the text Any suggestions or blaring issues I missed?
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
int num;
int k = atoi(argv[1]);
string output;
if(argc != 2)
{
printf("K not included in command");
return 1;
}
string s = get_string("Insert Lowercase Message:");
for (int i = 0, n = strlen(s); i < n; i++)
{
char c = s[i];
if (c >= 'A' && c <= 'Z')
{
num = 'A';
if (c >= 'a' && c <= 'z')
num = 'a';
printf("%c", (c - num + k) % 26 + num);
}
else
printf("%c", c);
}
}
You have your braces misaligned where you are testing the case of the letters. The way it is written, if a lowercase case letter is encountered, the uppercase test will fail and you will drop through to the else case. What you want is something like this:
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, string argv[])
{
int num;
int k;
string output;
char c;
if(argc != 2)
{
printf("K not included in command");
return 1;
}
k = atoi(argv[1]);
string s = get_string("Insert Lowercase Message:");
for (int i = 0; c = s[i]; i++)
{
if (isalpha(c))
{
if (isupper(c))
num = 'A';
else // islower
num = 'a';
printf("%c", (c - num + k) % 26 + num);
}
else
printf("%c", c);
}
}

Program is not printing spaces and puncuation

This code is supposed to encipher text based off the command argument input key and print out the enciphered text. However it doesn't print spaces and punctuation. Can someone explain what is wrong?
Example use:
$ ./caesar 12
world, say hello!
iadxp, emk tqxxa!
$
Code:
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
if (argc>2 || argc<2)
{
printf("Please enter a valid argument.\n");
return 1;
}
string input = GetString();
int key = atoi(argv[1]);
for(int i = 0, l = strlen(input); i < l; i++)
{
//if(isalpha(input[i]))
//{
char c = input[i];
int letternum = c;
if(isupper(c))
{
int upper = 'A';
int alphanum = letternum - upper;
int newint = (alphanum + key) % 26;
newint = newint + upper;
char newchar = newint;
printf("%c", newchar);
}
if(islower(c))
{
int lower = 'a';
int alphanum = letternum - lower;
int newint = (alphanum + key) % 26;
newint = newint + lower;
char newchar = newint;
printf("%c", newchar);
}
//}
}
printf("\n");
}
Add else after if() blocks.
Change from
if(isupper(c)) {
...
}
if(islower(c)) {
...
}
to
if(isupper(c)) {
...
} else if(islower(c)) {
...
} else {
putc(c);
}
Note: pedantic code would use the following as is...() functions are defined for all int values in the range of unsigned char and EOF.
isupper((unsigned char) c)
islower((unsigned char) c)
Note2: Code will have problems if alphanum + key < 0. May want to add a test to insure key is not too negative or use the following to insure key >= 0.
int key = atoi(argv[1]) % 26 + 26;
Note3: OP's code assumes A-Z and a-z are consecutive like in ASCII encoding (which is certainly the case 99.99+% of the time.) but not in EBCDIC

What's wrong with my CS50 Vigenere code?

I've been going round in circles with this now for a few hours. It manages the first word of the recommended test (Meet me at the park at eleven am) gets over the first spaces, gives a correct letter for m then prints several spaces before ending. Many thanks in advance.
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
int allstralpha();
int main(int argc, string argv[])
{
string keyw = argv[1];
if(argc == 2 && allstralpha(keyw))
{
string plaint = GetString();
int c = 0;
int kl = strlen(keyw);
int k = 0;
int p = 0;
int j = 0;
for(int i = 0, n = strlen(plaint); i < n; i++)
{
if(isalpha(plaint[i]))
{
if(isupper(keyw[j]))
{
k = keyw[(j % kl)] - 65;
if(isupper(plaint[i]))
{
p = plaint[i] -65;
c = ((k + p) % 26) + 65;
printf("%c", (char) c);
}
else if(islower(plaint[i]))
{
p = plaint[i] -97;
c = ((k + p) % 26) + 97;
printf("%c", (char) c);
}
}
else if(islower(keyw[j]))
{
k = keyw[(j % kl)] - 97;
if(isupper(plaint[i]))
{
p = plaint[i] - 65;
c = ((k + p) % 26) + 65;
printf("%c", (char) c);
}
else if(islower(plaint[i]))
{
p = plaint[i] - 97;
c = ((k + p) % 26) + 97;
printf("%c", (char) c);
}
}
j++;
}
else
{
printf("%c", (char) plaint[i]);
}
}
}
else
{
printf("Sorry that is not a vaild parameter\n");
return 1;
}
}
int allstralpha(string s)
{
for(int i = 0, n = strlen(s); i < n; i++)
{
if(!isalpha(s[i]))
{
return 0;
}
}
return 1;
}
int allstralpha();
int allstralpha(string s)
{
...
}
Your function definition and declaration don't match. You should declare int allstralpha(string s);
In first line of main:
int main(int argc, string argv[])
{
string keyw = argv[1];
...
}
First you should check if (argc > 1) before accessing argv[1]
For the actual code itself, you provide the plain text, but I can't see the keyword.
I use these values from wikipedia, vigenère cipher for testing:
Plaintext: ATTACKATDAWN
Key: LEMONLEMONLE
Ciphertext: LXFOPVEFRNHR
Minimum code to finish this:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(int argc, const char* argv[])
{
const char *str = "Meet me at the park at eleven am";
const char *key = "bacon";
int keylen = strlen(key);
int len = strlen(str);
for (int i = 0, j = 0; i < len; i++)
{
int c = str[i];
if (isalnum(c))
{
//int k = function of key and `j`...
//offset k...
if (islower(c))
{
c = (c - 'a' + k) % 26 + 'a';
}
else
{
c = (c - 'A' + k) % 26 + 'A';
}
j++;
}
putchar(c);
}
putchar('\n');
return 0;
}

Wrapping Text Using Modulo

I am trying to cipher some plain text using a string key. Anyway if the plain text is greater than the key the key is suppose to continue using the key..I have used modulo to make the key start over again but for some reason it is not working...what is wrong with the code? By the way the key status upper or lower status is not a factor so this is why I change it to lower. Any help rendered would be appreciated. //Code cleaned up as suggested.
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include<stdlib.h>
#include<ctype.h>
int main (int argc, string argv[])
{
if (argc != 2)
{
printf("Ouch missing key\n");
return 1;
}
//get encryption keyword from argv array
string k= (argv[1]);
//test for non aplha character in plain text message
int x;
for (x = 0; x <strlen(argv[1]); x++)
{
if(isalpha(k[x]) == false)
{
printf("Ouch ensure value is alphabetical only\n");
return 1;
}
}
string m;
m = GetString(); //get plain text from prompt
for (int i= 0, j = 0; i< strlen(m) && j<= strlen(k); i++, j++)
{
if (
isalpha(m[i]) && isupper(m[i]))
{
m[i]= (m[i]-'a' + (tolower(k[j % strlen(k)])-'a')) % 26 + 'A';
}
else if (
isalpha(m[i]) && islower(m[i])
)
{
m[i] = (m[i] - 'a' + (tolower(k[j %strlen(k)])- 'a')) % 26 + 'a';
}
else
m[i] = m[i];
}
printf("%s\n", m);
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <cs50.h>
int main (int argc, string argv[]){
if (argc != 2){
printf("Ouch missing key\n");
return 1;
}
string k = argv[1];
int len_k = strlen(k);
for (int i = 0; i < len_k; ++i){
if(isalpha(k[i]))
k[i] = tolower(k[i]);
else {
printf("Ouch ensure value is alphabetical only\n");
return 1;
}
}
string m;
m = GetString();
for (int i= 0; i< m[i] ; ++i){
if(isupper(m[i]))
m[i]= (m[i]-'A' + k[i % len_k] - 'a') % 26 + 'A';
else if(islower(m[i]))
m[i]= (m[i]-'a' + k[i % len_k] - 'a') % 26 + 'a';
else
m[i] = m[i];//no effect, no need
}
printf("%s\n", m);
free(m);
return 0;
}
If your coding language is C fix main() by,
int main (int argc, string argv[])
to
int main (int argc, char * argv[])

Resources