Decrypting Vernam Cipher - c

I'm creating a code for encryption and decryption for Vernam Cipher.
Initially, to encrypt a message, I would have to use a function that would generate my OTP. This function produces random numbers from 1-26 (to signify the english alphabet) and would be stored in an array of integers. The size is equal to the length of the message to be encrypted.
I was able to do that. My problem is how I would decrypt it.
I have this code.
My OTP array, since each element is randomized between 1-26, would signify an nth letter of the alphabet. e.g. 25 would signify the letter 'y' and so on.
The logic of my encryption is that since the size of my OTP array is equal to the length of my message, I would do XOR on each of the character of my message and my OTP. This is after converting my OTP array to corresponding letters of the alphabet depending on each element's randomized assigned number.
I was able to do the encryption part already. But whenever I try to decrypt, I get a different message from what I initially inputted.
void encryptiondecryption(char msg[], char key[]){
int i,j=0,x,m=0;
char output[100];
char output2[100];
/* Loop to remove all spaces in the message here*/
/*Encryption*/
int modd;
for(x = 0; msg[x]!='\0'; x++) {
printf("\nletter:%c - key:%c",msg[x], key[x] );
modd = (msg[x] ^ key[x]);
if(modd == 26){
output[x] = 'a'+ (modd%26)+25;
}else{
output[x] = 'a'+ (modd%26)-1;
}
}
output[x]='\0';
printf("\nEncrypted Message:\n");
for(x = 0; output[x]!='\0'; x++) {
printf("%c",output[x]);
}
/* decryption */
int modd2,diff,sum, toXOR;
printf("\n\ndecryption\n");
for(x = 0; output[x]!='\0'; x++) {
printf("\nletter:%c - key:%c",output[x], key[x] );
diff = output[x] - 'a';
if(diff == 25){
sum = diff - 25;
toXOR = sum + 26;
output2[x] = toXOR ^ key[x];
}else{
sum = diff + 1;
toXOR = sum + 26;
output2[x] = toXOR ^ key[x];
}
}
output2[x]='\0';
printf("\n Output for Decryption\n");
for(i = 0; output2[i]!='\0'; i++) {
printf("%c",output2[i]);
}
}
In addition, this is my generateOTP function.
char* generateKey(char msg[]){
srand(time(NULL));
int len = strlen(msg);
int numbers[len];
int x,y=0, m=0,a;
for(x=0;x<len;x++){
if(msg[x]!='_') m++;
}
printf("generated key is . . .\n");
int *getOTP = malloc (sizeof (int)*len);
for(x=0;x<m;x++){
getOTP[x] = rand() % (26 - 1 + 1) + 1;
}
for(x=0;x<m;x++){
printf("%d ", getOTP[x]);
}
char *letterOTP = malloc (sizeof (char) * len);
int getOTP2[m];
for(x=0;x<m;x++){
getOTP2[x] = getOTP[x];
}
int md;
for(x=0;x<m;x++){
md = (getOTP2[x]) % 26;
if(md ==0){
letterOTP[x] =( 97 + (md));
}else{
letterOTP[x] =( 97 + (md) - 1);
}
}
letterOTP[x] = '\0';
return letterOTP;
}
Basically, what this does as I have mentioned above, is that assigns a letter of an alphabet depending on what number an element in the array was randomly assigned to (e.g. 25 = 'y', 5 = 'e')

Related

Program don't encrypt the way I want (C language). From CS-50 lesson Vegenere

Program must encrypt plaintext by the key from command-line.
If p is some plaintext and k is a keyword (i.e., an alphabetical string, whereby A (or a) represents 0, B (or b) represents 1, C (or c) represents 2, …, and Z (or z) represents 25), then each letter, ci, in the ciphertext, c, is computed as:
ci = (pi + kj) % 26
Note this cipher’s use of kj as opposed to just k. And if k is shorter than p, then the letters in k must be reused cyclically as many times as it takes to encrypt p.
In other words, if Vigenère himself wanted to say HELLO to someone confidentially, using a keyword of, say, ABC, he would encrypt the H with a key of 0 (i.e., A), the E with a key of 1 (i.e., B), and the first L with a key of 2 (i.e., C), at which point he’d be out of letters in the keyword, and so he’d reuse (part of) it to encrypt the second L with a key of 0 (i.e., A) again, and the O with a key of 1 (i.e., B) again. And so he’d write HELLO as HFNLP, per the below:
In that way:
plaintext H E L L O
+key A B C A B
(shift value) 0 1 2 0 1
= ciphertext H F N L P
For example:
$ ./vigenere bacon
plaintext: Meet me at the park at eleven am
ciphertext: Negh zf av huf pcfx bt gzrwep oz
My case:
key: baz
plaintext: barfoo
expected: caqgon
my result: caqfgv
My code:
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
// Functions:
bool check_arguments(int argc);
bool is_key_alpha(string key);
int shift(char c);
int main(int argc, string argv[])
{
if (check_arguments(argc) == false)
{
return 1;
}
// Declaring key string variable:
string key = argv[1];
// Check containing any character that is not an alphabetic character
if (is_key_alpha(key) == false)
{
return 1;
}
// Prompting user for plaintext:
string plaintext = get_string("plaintext: ");
// Ecipher:
printf("ciphertext: ");
for (int i = 0; i < strlen(plaintext); i++)
{
if (islower(plaintext[i]))
{
printf("%c", ((plaintext[i]) - 97 + shift(key[i])) % 26 + 97);
}
else if (isupper(plaintext[i]))
{
printf("%c", ((plaintext[i]) - 65 + shift(key[i])) % 26 + 65);
}
else
{
printf("%c", plaintext[i]);
}
}
printf("\n");
return 0;
}
// FUNCTIONS :
// Checking if there's more than one command-line argument
// Checking if the command-line argument exists:
bool check_arguments(int argc)
{
// Checking if there's more than one command-line argument
if (argc > 2)
{
printf("Usage: ./vigenere keyword\n\n");
return false;
}
// Checking if the command-line argument exists:
else if (argc < 2)
{
printf("Usage: ./vigenere keyword\n");
return false;
}
// If okey:
else
{
return true;
}
}
// containing any character that is not an alphabetic character
bool is_key_alpha(string key)
{
for (int i = 0; i < strlen(key); i++)
{
if (isalpha(key[i]) == false)
{
printf("Key contains non-alphabetical chars");
return false;
}
}
return true;
}
// convert character into the correct shift value
int shift(char c)
{ // for ex. char = a == 97 ascii
if (isalpha(c))
{
if (isupper(c))
// The ASCII value of A is 65
{
c = c - 65;
}
else if (islower(c))
// The ASCII value of a is 97
{
c = c - 97;
}
}
else
{
return c;
}
return c;
}
Barry is on the right track. It is UB. On my system, I got: caqflr
If i hits the length of key, then key[i] goes beyond the end of key
Change:
shift(key[i])
Into:
shift(key[i % strlen(key)])
That fixes the bug.
But, the code is more complicated than it needs to be. That may be one reason why the issue was difficult to spot.
Also, the code runs slowly.
Using strlen when looping on a string changes the running time from O(n) to O(n^2). That's because strlen rescans the string on every loop iteration.
So, to fix this, change (e.g.):
for (int i = 0; i < strlen(plaintext); ++i)
Into:
for (int i = 0; plaintext[i] != 0; ++i)
Also, in such loops there is a lot of replicated code using plaintext[i].
Although the optimizer will understand this and produce fast code (i.e. cache the value and not refetch plaintext[i]), it can be simplified if we use an extra variable to contain the current value:
for (int i = 0, chr = plaintext[i]; chr != 0; chr = plaintext[++i])
Now, instead of using plaintext[i] in many places within the loop we can use chr
This is usually easier to read. And, ironically, is close/similar to the code the optimizer will generate.
The length of the key is invariant. So, we can precompute the value and just use it rather than recalculating it on every iteration of the plaintext loop.
Avoid using "magic numbers":
When you want 'A' use it instead of 65
When you want 'a' use it instead of 97
Also, shift can be improved / eliminated:
Because is_key_alpha checks with isalpha, key is guaranteed to be only alpha chars. So, no need for shift to use isalpha
We don't need to keep the original key value, only the modified one. That is, we can replace every value in key with the result of shift
In other words, we only need to do the shift operation for each key once, during initialization. We can have is_key_alpha do this.
Here is the refactored code:
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
// Functions:
bool check_arguments(int argc);
bool is_key_alpha(string key);
int shift(char c);
int
main(int argc, string argv[])
{
if (check_arguments(argc) == false) {
return 1;
}
// Declaring key string variable:
string key = argv[1];
// get the length of the key
// (1) cache it so we don't need to call strlen(key) in the loop (it's
// invariant)
// (2) because is_key_alpha transforms the key, calling strlen on key
// will no longer be valid
int klen = strlen(key);
// Check containing any character that is not an alphabetic character
if (is_key_alpha(key) == false)
return 1;
// Prompting user for plaintext:
string plaintext = get_string("plaintext: ");
// Ecipher:
printf("ciphertext: ");
for (int i = 0, chr = plaintext[i]; chr != 0; chr = plaintext[++i]) {
int k = key[i % klen];
if (islower(chr)) {
chr = ((chr - 'a') + k) % 26 + 'a';
}
else if (isupper(chr)) {
chr = ((chr - 'A') + k) % 26 + 'A';
}
printf("%c", chr);
}
printf("\n");
return 0;
}
// FUNCTIONS :
// Checking if there's more than one command-line argument
// Checking if the command-line argument exists:
bool
check_arguments(int argc)
{
// Checking if there's more than one command-line argument
if (argc > 2) {
printf("Usage: ./vigenere keyword\n\n");
return false;
}
// Checking if the command-line argument exists:
else if (argc < 2) {
printf("Usage: ./vigenere keyword\n");
return false;
}
// If okey:
else {
return true;
}
}
// containing any character that is not an alphabetic character
bool
is_key_alpha(string key)
{
// do what shift does and convert the key into offsets
for (int i = 0, chr = key[i]; chr != 0; chr = key[++i]) {
if (isupper(chr)) {
key[i] = chr - 'A';
continue;
}
if (islower(chr)) {
key[i] = chr - 'a';
continue;
}
printf("Key contains non-alphabetical chars");
return false;
}
return true;
}
// convert character into the correct shift value
int
shift(char c)
{ // for ex. char = a == 97 ascii
// The ASCII value of A is 65
// The ASCII value of a is 97
// NOTES:
// (1) is_key_alpha guarantees that the key value is an alpha
// (2) now that is_key_alpha computes the offset, this function is obsolete
if (isupper(c))
c -= 'A';
else if (islower(c))
c -= 'a';
return c;
}
We can tighten this up a bit further. shift is no longer needed. And, we can have is_key_alpha return the key length (-1 is error). Now, that it changes the key, we could rename it to be more descriptive of its function
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
// Functions:
bool check_arguments(int argc);
int key_transform(string key);
int
main(int argc, string argv[])
{
if (check_arguments(argc) == false) {
return 1;
}
// Declaring key string variable:
string key = argv[1];
// check and transform the key
int klen = key_transform(key);
if (klen < 0)
return 1;
// Prompting user for plaintext:
string plaintext = get_string("plaintext: ");
// Ecipher:
printf("ciphertext: ");
for (int i = 0, chr = plaintext[i]; chr != 0; chr = plaintext[++i]) {
int k = key[i % klen];
if (islower(chr)) {
chr = ((chr - 'a') + k) % 26 + 'a';
}
else if (isupper(chr)) {
chr = ((chr - 'A') + k) % 26 + 'A';
}
printf("%c", chr);
}
printf("\n");
return 0;
}
// FUNCTIONS :
// Checking if there's more than one command-line argument
// Checking if the command-line argument exists:
bool
check_arguments(int argc)
{
// Checking if there's more than one command-line argument
if (argc > 2) {
printf("Usage: ./vigenere keyword\n\n");
return false;
}
// Checking if the command-line argument exists:
else if (argc < 2) {
printf("Usage: ./vigenere keyword\n");
return false;
}
// If okey:
else {
return true;
}
}
// check and transform the key
// RETURNS: key length (-1=error)
int
key_transform(string key)
{
// do what shift does and convert the key into offsets
int i = 0;
for (int chr = key[i]; chr != 0; chr = key[++i]) {
if (isupper(chr)) {
key[i] = chr - 'A';
continue;
}
if (islower(chr)) {
key[i] = chr - 'a';
continue;
}
printf("Key contains non-alphabetical chars");
return -1;
}
return i;
}

the int value changed in For loop without being calculated

i am new to c, and I am building a cipher text converter. I have a main function to take a Key value (int k) from the user and pass that value to this function:
int ciphertextCoverter (int k)
{
printf("key=%i\n",k);
char ciphertext[] = "";
string plaintext = get_string("plaintext: ");
for (int n = 0, x = strlen(plaintext); n < x; n++)
{
printf("key in FOR loop: %i",k);
if isupper(plaintext[n])
{
printf("key in IF loop: %i",k);
ciphertext[n] = (plaintext[n] - 'A'+ k ) % 26 + 65;
printf("plaintext- %i %c %i %i %i %i %i\n",k, plaintext[n],plaintext[n], plaintext[n]-'A', (plaintext[n] - 'A'+ k), (plaintext[n] - 'A'+ k) % 26, (plaintext[n] - 'A'+ k) % 26+ 65);
}
else
{
ciphertext[n] = (plaintext[n] - 'a'+ k) % 26 + 97;
}
}
printf("ciphertext: %s\n",ciphertext);
return 0;
}
I used printf to find out that the value of int k which I passed on from the main function has changed value in the for loop, but I want to stay as a const. Please help me! what have I done wrong?
You are declaring ciphertext as an array of size 1, so you cannot write any data to it. Give it some size; something like:
string plaintext = get_string("plaintext: ");
char ciphertext[strlen(plaintext) + 1];
should work. Just remember to write the null terminator at the end: ciphertext[x] = '\0'
You have declared character array of size 1. And you are storing x characters in ciphertext[]. First declare array of any size or create array dynamically.
char ciphertext[] = "";

C Extract Infix (char array) and cast to int

Given a string/char array e.g :
99+(88-77)*(66/(55-44)+33)
How do I extract the numbers and operators?
I would like to store them into two stacks a and b each containing number and operators only.
I am not sure on the logic, I was thinking of scanning each char in the char array, adding the char (number) into another char, until it meets an operator. Then I go to the char(number) and concatenate the string.
Is there a better way to do this, preferabbly without external libraries?
As pointed out in comments, you can try using strtol for scanning integers from input string. I tried the suggested approach and it seemed to work for me for the provided test case. I haven't tested this for corner cases, but this should give you better idea of what users in comments are saying:
int main() {
char input[30] = "99+(88-77)*(66/(55-44)+33)";
// Initialize Stack Indices
operandStackIndex = 0;
operatorStackIndex = 0;
// Our markers for strtol()
char *pStart = input;
char *pEnd;
long ret;
while ((ret = convertStringToLong(pStart, &pEnd, 10)) > 0) {
operandStack[operandStackIndex++] = ret;
pStart = pEnd;
while (isOperator(*pStart)) { // Check whether character it '+','-','/','(',')','*'..
operatorStack[operatorStackIndex++] = *pStart;
pStart++;
}
}
printf("Operand Stack:\n");
for (int i = operandStackIndex - 1; i >= 0; i--)
printf("%d\n", operandStack[i]);
printf("Operator Stack:\n");
for (int i = operatorStackIndex - 1; i >= 0; i--)
printf("%c\n", operatorStack[i]);
}
Here is simple implementation for convertStringToLong method(alternative to strtol):
long convertStringToLong(char* pStart, char** pEnd, int base) {
long num = 0;
while (isDigit(*pStart)) {
num = num * base + (*pStart - '0');
pStart++;
}
*pEnd = pStart;
return num;
}
When I ran this, I was able to see expected output:
Operand Stack:
33
44
55
66
77
88
99
Operator Stack:
)
+
)
-
(
/
(
*
)
-
(
+

Cipher Function Producing Unwanted Results in the Last Character of Output

I have been spending all day trying to figure out what I did wrong with this enciphering function I created.
The function works by taking in a keyword which it then converts to an ASCII values and then takes that value and formats it into something that will work with an alphabetical index eg: A= 0, B= 1, C= 2, etc... It then converts all of the plain text using the same method. After that it shifts over the characters of the plain text and then adds the characters value from the keyword iterating over the keyword in a loop until it is done encrypting the plain text.
It works for all my tests except for one which went like this:
Keyword is BaZ
input:
plaintext: BaRFoo
output:
ciphertext: CaQGoh
but the desired output is
ciphertext: CaQGon
I am using the following encipher function:
void encipher(char* plainText, char*key)
{
printf("ciphertext: ");
char alphabeticalIndex[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
int currentKeyChar = 0;
for(int i = 0, n = strlen(plainText); i < n; i++)
{
// check if the end of they key has been reached, if so then reset it
if(currentKeyChar >= strlen(key)) currentKeyChar = 0;
if(isalpha(plainText[i]) == false) printf("%c", plainText[i]);
if(isupper(plainText[i]))
{
// find the cipher character as an int then add it as the key to captialCharNum
int capitalCipherCharNum = ((int) key[currentKeyChar] - 65);
int capitalCharNum = (((int) plainText[i] - 65) + capitalCipherCharNum) % 26;
printf("%c", toupper(alphabeticalIndex[capitalCharNum]));
}
if(islower(plainText[i]))
{
// same as it was for capitals but in this case its lowercase
int lowerCipherCharNum = ((int) key[currentKeyChar] - 97);
int lowerCharNum = (((int) plainText[i] - 97) + lowerCipherCharNum) % 26;
printf("%c", tolower(alphabeticalIndex[lowerCharNum]));
}
currentKeyChar++;
}
printf("\n");
}
Your error is here:
int lowerCipherCharNum = ((int) key[currentKeyChar] - 97);
When key[currentKeyChar] is uppercase, lowerCipherCharNum is negative, resulting in your cipher value being wrong. To fix the problem you need:
int lowerCipherCharNum;
if (islower (key[currentKeyChar]))
lowerCipherCharNum = key[currentKeyChar] - 'a';
else
lowerCipherCharNum = key[currentKeyChar] - 'A';
This will correct your expected output.
While there is nothing wrong with using array indexing to work your way down each string, using pointer arithmetic can greatly simplify your code. (you also have unnecessary and repeated calls to strlen that should be removed (or at least minimized by computing the length of key once rather than every time you check it.))
An example of how using pointer arithmetic can simplify your logic (and shortening your variable names because I don't like to type), you could do something similar to the following:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void encipher (const char *plaintext, const char *key)
{
const char *aidx = "abcdefghijklmnopqrstuvwxyz",
*p = plaintext,
*k = key;
printf ("ciphertext: ");
while (*p) {
if (isalpha (*p) == 0) printf ("%c", *p);
if (isupper (*p)) {
/* find the cipher character as an int then add it as the key */
int ccicn = (*k - 'A');
int ccnum = (*p - 'A' + ccicn) % 26;
putchar (toupper (aidx[ccnum]));
}
if (islower (*p)) {
/* same as it was for capitals but in this case its lowercase */
int lcicn = islower (*k) ? *k - 'a' : *k - 'A';
int lcnum = (*p - 'a' + lcicn) % 26;
putchar (aidx[lcnum]);
}
p++;
if (*k) k++;
if (!*k) k = key;
}
putchar ('\n'); /* don't use printf for one-character */
}
int main (int argc, char **argv) {
const char *s = argc > 1 ? argv[1] : "BaRFoo",
*key = argc > 2 ? argv[2] : "BaZ";
encipher (s, key);
return 0;
}
Example Use/Output
$ ./bin/encipher
ciphertext: CaQGon
(note: the comment /* don't use printf for one-character */)
While not an error, the standard coding style for C avoids the use of camelCase or MixedCase variable names in favor of all lower-case while reserving upper-case names for use with macros and constants. It is a matter of style -- so it is completely up to you, but failing to follow it can lead to the wrong first impression in some circles.
Below is an "edited" version of your encipher function with a few additional thoughts in comments and the code spaced a little wider (which you may appreciate more as your eyes get older)
/* if plainText and key are not modified, pass them as 'const char *' */
void encipher (const char *plainText, const char *key)
{
/* place variables before executed code if you have the option...
* (just increases portability to older compilers (like Win7))
*/
char alphabeticalIndex[26] = "abcdefghijklmnopqrstuvwxyz";
int currentKeyChar = 0;
size_t keylen = strlen (key);
printf ("ciphertext: ");
for (int i = 0, n = strlen (plainText); i < n; i++)
{
// check if the end of they key has been reached, if so then reset it
if (currentKeyChar >= (int)keylen) currentKeyChar = 0;
if (isalpha (plainText[i]) == 0) putchar (plainText[i]);
if (isupper (plainText[i]))
{
// find the cipher character as an int then add it as the key
int capitalCipherCharNum = ((int) key[currentKeyChar] - 65);
int capitalCharNum = (plainText[i] - 65 + capitalCipherCharNum) % 26;
putchar (toupper (alphabeticalIndex[capitalCharNum]));
}
if (islower (plainText[i]))
{
// same as it was for capitals but in this case its lowercase
// int lowerCipherCharNum = ((int) key[currentKeyChar] - 97);
int lowerCipherCharNum;
if (islower (key[currentKeyChar]))
lowerCipherCharNum = key[currentKeyChar] - 'a';
else
lowerCipherCharNum = key[currentKeyChar] - 'A';
int lowerCharNum = (plainText[i] - 97 + lowerCipherCharNum) % 26;
putchar (tolower (alphabeticalIndex[lowerCharNum]));
}
currentKeyChar++;
}
putchar ('\n'); /* don't use printf for one-character */
}
Look things over and let me know if you have further questions.

My executable stops running when I try to runmy program in Eclipse CDT

After I build my project, I seem to be getting this message where it says that my program Cyber Dojo 1 has stopped working. This is shown below:
Now there are a few resources online, including:
This SO post, which has one answer that has not been accepted. The answer is not valid, as I do not have any arguments for my program.
This forum post itself on the Eclipse Community Forums. This has a few good suggestions, especially the one that relates to changing MinGW's linker flags. However, this would apply to a C++ program and not a C program. This is also a post that deals with the same problem, but once again, for C++.
And that is why I am currently looking for a solution for this problem for a C program on my Eclipse CDT.
Here is my code:
//Checking number as input
static void isNotValidCharacter1(void)
{
assert(answer('3') == NULL);
}
//Checking special character
static void isNotValidCharacter2(void)
{
assert(answer('!') == NULL);
}
//Checking lowercase letter
static void isNotValidCharacter3(void)
{
assert(answer('c') == NULL);
}
static void validCharacter(char **sample_answer)
{
int i, j;
for (i = 1; i < 11; i++) {
for (j = 1; j < 11; j++) {
assert((answer('F'))[i][j] == sample_answer[i][j]);
}
}
}
//Random Number Corner Checks Follow:
// Randomly creates a number/ character and checks the leftmost and rightmost corner characters
// as the character itself
static char psuedoRandomNumberGeneratedCharacterCheck1(void)
{
// Creating the random number between 65 and 90
int rn;
srand(time(NULL));
rn = (rand() % 25) + 65;
int distA = rn - 65;
//converting it to a character
char c_rn = (char)rn;
//checking the leftmost and rightmost corner characters
assert(answer(rn)[distA][0] == c_rn);
assert(answer(rn)[distA][distA*2] == c_rn);
return c_rn;
}
// Randomly creates a number/ characters and the checks the uppermost and lowermost corner characters
// corners as 'A'
static char psuedoRandomNumberGeneratedCharacterCheck2(void)
{
// Creating the random number between 65 and 90
int rn;
srand(time(NULL));
rn = (rand() % 25) + 65;
int distA = rn - 65;
//converting it to a character
char c_rn = (char)rn;
//checking the uppermost and lowermost corner characters
assert(answer(rn)[0][distA] == 'A');
assert(answer(rn)[distA*2][distA] == 'A');
return c_rn;
}
static void validCharacterA(void)
{
char **aDiamond = answer('A');
aDiamond[0][0] = 'A';
}
int main(void)
{
//Not valid character tests
isNotValidCharacter1();
puts("Number not accepted");
puts("special pause for debugging");
isNotValidCharacter2();
puts("Special Character not accepted");
isNotValidCharacter3();
puts("lowercase not accepted");
//Psuedorandom Tests
char prc1 = psuedoRandomNumberGeneratedCharacterCheck1();
printf("random character '%c' chosen and the leftmost and rightmost corner characters", prc1);
char prc2 = psuedoRandomNumberGeneratedCharacterCheck2();
printf("random character '%c' chosen and the leftmost and rightmost corner characters", prc2);
// Acid Test for the letter 'F'
//Square of 11 letters declared
char **Fanswer = malloc(11 * sizeof(*Fanswer));
int i;
for (i =0; i <11; i++) {
Fanswer[i] = malloc(11 * sizeof(char));
}
strcpy( Fanswer[0], " A ");
strcpy( Fanswer[1], " B B ");
strcpy( Fanswer[2], " C C ");
strcpy( Fanswer[3], " D D ");
strcpy( Fanswer[4], " E E ");
strcpy( Fanswer[5], "F F");
strcpy( Fanswer[6], " E E ");
strcpy( Fanswer[7], " D D ");
strcpy( Fanswer[8], " C C ");
strcpy( Fanswer[9], " B B ");
strcpy(Fanswer[10], " A ");
validCharacter(Fanswer);
puts("answer for F is correct");
validCharacterA();
puts("Answer for A is correct");
//All tests have passed and the end of the program
puts("All tests passed");
}
And my program for answer() is as follows:
char** answer(char c)
{
if (check(c)) {
printf("\n");
} else {
printf("Not a valid character\n");
return NULL;
}
//--------------------------------------------------------------------------------------------------------
// Preprocessing
//--------------------------------------------------------------------------------------------------------
//processing declarations
int ascii = (int)c;
int distA = ascii - 'A';
//Number of Rows and Columns
int n = ( distA * 2 ) + 1;
//Declare the column of pointers
char **diamond = malloc(n * sizeof(*diamond));
//Declare the row of characters
// 2D array declared here to save on computation in situations where characters are not valid
int i;
for (i=0; i<n; i++) {
diamond[i] = malloc(n * sizeof(char));
}
//--------------------------------------------------------------------------------------------------
// Processing
//--------------------------------------------------------------------------------------------------
//Fill in the Array
if (n == 1) {
diamond[0][0] = c;
} else {
diamond[distA][0] = c;
diamond[distA][distA*2] = c;
for (i = 1; i <= distA; i++) {
diamond[distA-i][i] = (char)(ascii - i);
diamond[distA-i][(distA*2)-i] = (char)(ascii - i);
diamond[distA+i][i] = (char)(ascii - i);
diamond[distA+i][(distA*2)-i] = (char)(ascii - i);
}
}
//-------------------------------------------------------------------------------------------------
// Postprocessing
//---------------------------------------------------------------------------
return diamond;
}
If you are a beginer with Eclipse and you don't know how to use a debugger, you can look some tutorial.
https://www.youtube.com/watch?v=azInZkPP56Q
But even after this tutorial you have difficulty to making your debuger works (because sometimes it depends how installed your Eclipse, your compiler and other things), you can try to put a big part of your code in comment and see if the problem is gone. And little by little reduce the amount of code you put in comment. When the bug reapear it means it's somewhere inside the part you removed the comment recently.
The last method is not the best way to debug your program but can be usefull for beginners and give you another alternative if you have difficulty to use your debugger.

Resources