-
-
Save teeschorle/cc998f1ef47e270282d3d4fa3d217d31 to your computer and use it in GitHub Desktop.
//CS50 Problem Set 2 (Fall 2019): Substitution | |
//Author: teeschorle | |
#include <stdio.h> | |
#include <cs50.h> | |
#include <string.h> | |
#include <ctype.h> | |
bool validate(string key); | |
int main(int argc, string argv[]) | |
{ | |
if (argc == 2) | |
{ | |
string key = argv[1]; | |
if (validate(key) == true) | |
{ | |
string plaintext = get_string("plaintext: "); | |
int charcount = strlen(plaintext); | |
char ciphertext[charcount]; | |
string abc = "abcdefghijklmnopqrstuvwxyz"; | |
for (int i = 0; i < charcount; i++) | |
{ | |
if (isupper(plaintext[i]) != 0) | |
{ | |
for (int j = 0; j < 26; j++) | |
{ | |
if(abc[j] == tolower(plaintext[i])) | |
{ | |
ciphertext[i] = toupper(key[j]); | |
break; | |
} | |
} | |
} | |
else if (islower(plaintext[i]) != 0) | |
{ | |
for (int j = 0; j < 26; j++) | |
{ | |
if(abc[j] == plaintext[i]) | |
{ | |
ciphertext[i] = tolower(key[j]); | |
break; | |
} | |
} | |
} | |
else | |
{ | |
ciphertext[i] = plaintext[i]; | |
} | |
} | |
printf("ciphertext: %s\n", ciphertext); | |
return 0; | |
} | |
else | |
{ | |
printf("Please make sure your key is a permutation of all 26 characters - not more, not less.\n"); | |
return 1; | |
} | |
} | |
else | |
{ | |
printf("Input error. Please provide a single key.\n"); | |
return 1; | |
} | |
} | |
bool validate(string key) | |
{ | |
int matches = 0; | |
if (strlen(key) == 26) | |
{ | |
for (char c = 'a'; c <= 'z'; c++) | |
{ | |
for (int i = 0; i < 26; i++) | |
{ | |
if(tolower(key[i]) == c) | |
{ | |
matches++; | |
break; | |
} | |
} | |
} | |
if(matches == 26) | |
{ | |
return true; | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
else | |
{ | |
return false; | |
} | |
} |
include <stdio.h>
include <cs50.h>
include <string.h>
include <ctype.h>
bool check(string key);
int main(int argc, string argv[])
{
if (argc == 2)
{
string key = argv[1];
if (check(key) == true)
{
string text = get_string("Enter plaintext : ");
int textlenth = strlen(text);
char cipher[textlenth];
string alpha = "abcdefghijklmnopqrstuvwxyz";
for (int j = 0; j < textlenth; j++)
{
if (isupper(text[j]) != 0)
{
for (int k = 0; k < 26; k++)
{
if (alpha[k] == tolower(text[j]))
{
cipher[j] = toupper(key[k]);
break;
}
}
}
else if (islower(text[j]) != 0)
{
for (int k = 0; k < 26; k++)
{
if (alpha[k] == text[j])
{
cipher[j] = tolower(key[k]);
break;
}
}
}
else
{
cipher[j] = text[j];
}
}
cipher[textlenth] = '\0';
printf("ciphertext: %s\n", cipher);
return 0;
}
else
{
printf("Usage: ./substitution key\n");
return 1;
}
}
else
{
printf("Usage: ./substitution key\n");
return 1;
}
}
bool check(string key)
{
int same = 0;
if (strlen(key) == 26)
{
for (char c = 'a'; c <= 'z'; c++)
{
for (int n = 0 ; n < 26; n++)
{
if (tolower(key[n]) == c)
{
same++;
break;
}
}
}
if (same == 26)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
Hi all,
I am writing this to help all of those who ran into a similar issue with the code not passing all test cases and returning random characters at the end. This is because we are dealing with adding chars to a new array and returning that new array as a string. Recall from the lectures that a string ends with '\0' so the code does not pass all cases because it's returning as a string of chars but no '\0'
Please find code attached for your reference
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
bool validate(string key);
int main(int argc, string argv[])
{
if (argc == 2)
{
string key = argv[1];
if(validate(key) == true)
{
string plaintext = get_string("plaintext: ");
int charcount = strlen(plaintext);
char ciphertext[charcount];
string abc = "abcdefghijklmnopqrstuvwxyz";
for(int i = 0; i < charcount; i++)
{
if(isupper(plaintext[i]) != 0)
{
for(int j = 0; j < 26; j++)
{
if(abc[j] == tolower(plaintext[i]))
{
ciphertext[i] = toupper(key[j]);
break;
}
}
}
else if(islower(plaintext[i])!=0)
{
for(int j = 0; j < 26; j++)
{
if (abc[j] == plaintext[i])
{
ciphertext[i] = tolower(key[j]);
break;
}
}
}
else
{
ciphertext[i] = plaintext[i];
}
}
ciphertext[charcount] = '\0';
printf("ciphertext: %s\n", ciphertext);
return 0;
}
else
{
printf("Please make sure your key is a permutation of all 26 characters - not more, not less.\n");
return 1;
}
}
else
{
printf("Input error. Please provide a key.");
return 1;
}
}
bool validate(string key)
{
int matches = 0;
if (strlen(key) == 26)
{
for (char c = 'a'; c <= 'z'; c++)
{
for (int i = 0; i < 26; i++)
{
if(tolower(key[i]) == c)
{
matches++;
break;
}
}
}
if(matches == 26)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
include <stdio.h>
include <cs50.h>
include <string.h>
include <ctype.h>
bool check(string key);
int main(int argc, string argv[])
{
if (argc == 2)
{string key = argv[1]; if (check(key) == true) { string text = get_string("Enter plaintext : "); int textlenth = strlen(text); char cipher[textlenth]; string alpha = "abcdefghijklmnopqrstuvwxyz"; for (int j = 0; j < textlenth; j++) { if (isupper(text[j]) != 0) { for (int k = 0; k < 26; k++) { if (alpha[k] == tolower(text[j])) { cipher[j] = toupper(key[k]); break; } } } else if (islower(text[j]) != 0) { for (int k = 0; k < 26; k++) { if (alpha[k] == text[j]) { cipher[j] = tolower(key[k]); break; } } } else { cipher[j] = text[j]; } } cipher[textlenth] = '\0'; printf("ciphertext: %s\n", cipher); return 0; } else { printf("Usage: ./substitution key\n"); return 1; } } else { printf("Usage: ./substitution key\n"); return 1; }
}
bool check(string key)
{
int same = 0;if (strlen(key) == 26) { for (char c = 'a'; c <= 'z'; c++) { for (int n = 0 ; n < 26; n++) { if (tolower(key[n]) == c) { same++; break; } } } if (same == 26) { return true; } else { return false; } } else { return false; }
}
Thanks! This really help me out this problem
those answers are so long and complicated. Here is my solution:
`#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
bool check (string s);
bool check (string s)
{
int j, j2;
if (strlen(s) != 26)
{
return false;
}
for (j = 0; j < strlen(s); ++j)
{
for (j2 = j + 1; j2 < strlen(s); ++j2)
{
if (s[j]==s[j2])
{
return false;
}
}
}
for (j = 0; j < strlen(s); ++j)
{
if (isalpha(s[j])==0)
{
return false;
}
}
return true;
}
int main(int c5, string v[])
{
if (c5 != 2)
{
printf ("Wrong Input type. Exp: ./subtitution VcHpRzGjNtLsKfBdQwAxEuYmOi\n");
return 1;
}
int sl = strlen(v[1]);
string cr = v[1];
if (check(v[1])==true)
{
char carr [2][26], c2 [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (int j = 0; j<26;++j)
{
carr[0][j] = cr[j];
carr[1][j] = c2[j];
}
string p2 = get_string("Plain Text: ");
string p3=p2;
int b = 0;
for (;b<strlen(p2); ++b)
{
for (int g = 0; g<26; ++g)
{
if (p2[b] == tolower(carr[1][g]))
{
p3[b] = tolower(carr[0][g]);
break;
}
else if (p2[b] == carr[1][g])
{
p3[b] = toupper((carr[0][g]));
break;
}
else
p3[b] = p2[b];
}
}
printf ("ciphertext: %s\n", p3);
}
else
{
printf ("Key must contain 26 characters.\n");
return 1;
}
}`
Since every one is posting their codes here I thought why not do the same. If some one reads this, please critique on my code so I get better at coding. thankyou :)
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
string ciphertext(string plain, string key);
int main(int argc, string argv[])
{
//To check if arguments are 2 and numeric
if (argc == 2)
{
string key = (argv[1]);
if (strlen(key) == 26) //To check key length
{
printf("%s\n", key);
for (int i = 0; (key[i]) != '\0'; i++)
{
if (isdigit(key[i])) //To check if key conatains digit
{
printf("Key must only cntain alphabetic characters.\n");
return 1;
}
if (isalpha(key[i])) //To check if key is alphabetical //To check if alphabet is double in key
{
for (int j = i + 1; key[j] != '\0'; j++)
{
if (key[i] == key[j])
{
printf("Key must not contain repeated characters.\n");
return 1;
}
}
}
}
//main code
string plain = get_string("plaintext:");
string cipher = ciphertext(plain, key); //calling function to cipher
printf("ciphertext: %s\n", cipher);
return 0;
}
else //To check length of key
{
printf("Key must contain 26 characters.\n");
return 1;
}
}
if (argc != 2) //To check if arguments are 2
{
printf("Usage: ./substitution key\n");
return 1;
}
}
string ciphertext(string plain, string key)
{
string c = plain;
string k = key;
string abc = "abcdefghijklmnopqrstuvwxyz";
for (int i = 0; plain[i] != '\0'; i++)
{
if (islower(plain[i]) != 0)
{
for (int j = 0; k[j] != '\0'; j++)
{
if (abc[j] == (plain[i]))
{
c[i] = tolower(k[j]);
break;
}
}
}
else if (isupper(plain[i]) != 0)
{
for (int j = 0; k[j] != '\0'; j++)
{
if (toupper(abc[j]) == plain[i])
{
c[i] = toupper(k[j]);
break;
}
}
}
else
{
c[i] = plain[i];
}
}
return c;
}
This function returns a non-zero int if c is an uppercase letter and 0 if c is not an uppercase letter.
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, string argv[])
{
if (argc != 2 || !isalpha(*argv[1]))
{
printf("Usage: ./sub key\n");
return (1);
}
string key = argv[1];
if (strlen(key) != 26)
{
printf("Usage: ./sub key\n");
return (1);
}
string s = get_string("Plaintext: ");
printf("Ciphertext: ");
for (int i = 0, n = strlen(s); i < n; i++)
{
if (isupper(s[i]))
{
char u = s[i];
char m = 'A';
if (islower(s[i]))
m = 'a';
printf("%c",key[u - m] );
}
else
{
printf("%c",s[i]);
}
}
printf("\n");
return(0);
}
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
bool validate_key(string key);
int main(int argc, string argv[])
{
//checks if key is the right length
if (argc != 2 || strlen(argv[1]) != 26 || validate_key((string) argv[1]) != 1)
{
printf("Key must exist and contain 26 non identical alphabetical characters.\n");
return 1;
}
//gets input text
string text = get_string("plaintext: ");
int len = strlen(text);
char mychar = toupper(text[0]) - 65;
for (int i = 0; i < len; i++)
{
if (mychar >= 0 && mychar <= 26)
{
if (isupper(text[i]))
{
text[i] = toupper((char) argv[1][(int) mychar]);
}
else
{
text[i] = tolower((char) argv[1][(int) mychar]);
}
}
mychar = toupper(text[i + 1]) - 65;
}
printf("ciphertext: %s\n", text);
return 0;
}
bool validate_key (string key)
{
int len = strlen(key);
char mychar;
for(int i = 0; i < len; i++)
{
mychar = toupper(key[i]);
if(mychar >= 65 && mychar <= 90)
{
for(int j = i + 1; j < len; j++)
{
if(mychar == toupper(key[j]))
{
return 0;
}
}
}
else
{
return 0;
}
}
return 1;
}
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
//get the input from the user in comomand-line
int main (int argc, string argv[])
{
if (argc == 2) // Checks if it is two arugument including file name
{
int len = strlen(argv[1]);
for (int i = 0; i < len; i++) // Checks if it is a digit, if yes, then print the following
{
if (isdigit(argv[1][i]))
{
printf("Usage: ./substitution key \n");
exit(0); // To terminate the program immediately
}
}
if (len != 26) // Checks if the length of the given input in command-line is 26 characters, if not, then print
{
printf("key must contain 26 characters.");
}
string plain = get_string("Plain text: "); //Get plain text from the user to encode it
string cipher;
printf("Cipher text: ");
for (int i = 0, n = strlen(plain); i < n; i++)
{
if (islower(plain[i])) // Checks the case sensitive
{
printf("%c", tolower(argv[1][plain[i] - 'a'])); // prints lower case cipher calue
}
else if (isupper(plain[i]))
{
printf("%c", toupper(argv[1][plain[i] - 'A'])); //prints upper case cipher value
}
else
{
printf("%c", plain[i]); // prints apart from alphabetical characters
}
}
}
else
{
printf("Usage: ./substitution key");
}
}
If anyone is struggling with this like I did, its highly likely that we created this "ciphertext" been working differently as we expected.
if you recall from the lecture, all string has an char of '\0' at the end of it. If we loop through our plaintext and 'append'/put the ciphered character into this new array, you would need to add '\0' at ciphertext[strlen(plaintext)] to finish up the string. Or i guess something to do with the memory structure, it will add random chars at the end of the operations.
In short: add the extra char '\0' at the end of your ciphered text.