C Gives strange output when variable scope changes - c

C does some spooky things when I put the nonAlphaCount declaration above the for loop. I can't explain why the outputs are different.
For version 1 (int declaration above main method) my input output was:
INPUT: ./Vigenere.exe bacon
Enter plain text: Meet me at the park at eleven am
OUTPUT: Negh zf av huf pcfx bt gzrwep oz
For version 2 ( int declaration above for loop )
INPUT: ./Vigenere.exe bacon
Enter plain text: Meet me at the park at eleven am
OUTPUT: NRQQ M[L \M^^ KQXXZQZ M
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
const int INPUT_LEN = 255;
const int ALPHABET_LEN = 26;
int nonAlphaCount = 0;
int main (int count, char *args[])
{
char plainText[INPUT_LEN];
char *cipherText;
char *keyWord;
if ( count < 2 || count > 2)
{
printf("There is no key");
return 1;
}
strcpy(keyWord, args[1]);
int keyWord_LEN = strlen(keyWord);
printf("Enter plain text: ");
fgets (plainText, INPUT_LEN, stdin);
int strLength = strlen(plainText);
cipherText = malloc(strLength);
printf("%s", plainText);
for (int i = 0; i < strLength; i++ ){
if(plainText[i] == '\0' || plainText[i] == '\n'|| plainText[i] == '\r')
break;
if(isalpha(plainText[i]))
{
// Default lower
int asciiUpperOrLower = 97;
int keyUpperOrLower = 97;
if(isupper(plainText[i]))
asciiUpperOrLower = 65;
if(isupper(keyWord[i % keyWord_LEN]))
keyUpperOrLower = 65;
int Key = keyWord[(i - nonAlphaCount) % keyWord_LEN] - keyUpperOrLower;
int alphabetBaseletter = ((plainText[i] - asciiUpperOrLower + Key) % ALPHABET_LEN);
cipherText[i] = alphabetBaseletter + asciiUpperOrLower;
}
else{
cipherText[i] = plainText[i];
nonAlphaCount++;
}
}
// Set string terminator.
cipherText[strLength - 1] = '\0' ;
printf("%s", cipherText);
return 0;
}
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
const int INPUT_LEN = 255;
const int ALPHABET_LEN = 26;
int main (int count, char *args[])
{
char plainText[INPUT_LEN];
char *cipherText;
char *keyWord;
if ( count < 2 || count > 2)
{
printf("There is no key");
return 1;
}
strcpy(keyWord, args[1]);
int keyWord_LEN = strlen(keyWord);
printf("Enter plain text: ");
fgets (plainText, INPUT_LEN, stdin);
int strLength = strlen(plainText);
cipherText = malloc(strLength);
printf("%s", plainText);
**int nonAlphaCount = 0;**
for (int i = 0; i < strLength; i++ ){
if(plainText[i] == '\0' || plainText[i] == '\n'|| plainText[i] == '\r')
break;
if(isalpha(plainText[i]))
{
// Default lower
int asciiUpperOrLower = 97;
int keyUpperOrLower = 97;
if(isupper(plainText[i]))
asciiUpperOrLower = 65;
if(isupper(keyWord[i % keyWord_LEN]))
keyUpperOrLower = 65;
int Key = keyWord[(i - nonAlphaCount) % keyWord_LEN] - keyUpperOrLower;
int alphabetBaseletter = ((plainText[i] - asciiUpperOrLower + Key) % ALPHABET_LEN);
cipherText[i] = alphabetBaseletter + asciiUpperOrLower;
}
else{
cipherText[i] = plainText[i];
nonAlphaCount++;
}
}
// Set string terminator.
cipherText[strLength - 1] = '\0' ;
printf("%s", cipherText);
return 0;
}

Both programs exhibit undefined behaviour in
char *keyWord;
...
strcpy(keyWord, args[1]);
which is revealed by the compiler warning: "uninitialized local variable 'keyWord' used". You have not allocated any memory.
If one of the programs happened to work, so be it.

Related

Strange char appears in the output

I'm trying to obfuscate word which is stored in string and my code sometimes works and sometimes doesn't. Here is my code:
// main function
int main(int argc, string argv[])
{
string k, plaintext;
int size, i = 0, key = 0;
k = argv[1];
size = strlen(k);
if (argc < 2 || !isNummeric(k, size) || k < 0)
return 1;
else
plaintext = GetString();
size = strlen(plaintext);
char ciphertext[size];
key = atoi(k);
while(i < size)
{
if (isalpha(plaintext[i]))
{
encipher(key, i, &ciphertext[i], plaintext);
}
else
{
ciphertext[i] = plaintext[i];
}
i++;
}
printf("%s\n",ciphertext);
}
A key is received from the user to shift each letter and I need to check whether the key is numeric value or not so I made isNummeric function to do that
bool isNummeric(string k, int size)
{
int c=0;
for(int i=0; i<size; i++)
{
if(!isdigit(k[i]))
c++;
}
if(c==0)
return true;
return false;
}
Now to encipher I made function to shift each letter:
void encipher(int k, int i, char *pt, string plaintext)
{
int p, c;
if(islower(plaintext[i]))
{
p=plaintext[i]-'a';
c=(p+k)%26;
*pt=c+97;
}
else
{
p=plaintext[i]-'A';
c=(p+k)%26;
*pt=c+65;
}
}
Assembling multiple comments from the question into fixed code yields the following code which seems to work:
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
static bool isNumeric(string k, int size)
{
for (int i = 0; i < size; i++)
{
if (!isdigit((unsigned char)k[i]))
return false;
}
return true;
}
/* There are too many arguments to this function - but it works */
static void encipher(int k, int i, char *pt, string plaintext)
{
int p, c;
if (islower((unsigned char)plaintext[i]))
{
p = plaintext[i] - 'a';
c = (p + k) % 26;
*pt = c + 'a';
}
else
{
p = plaintext[i] - 'A';
c = (p + k) % 26;
*pt = c + 'A';
}
}
int main(int argc, string argv[])
{
string k = argv[1];
if (argc < 2 || !isNumeric(k, strlen(k)))
return 1;
string plaintext = GetString();
int size = strlen(plaintext);
char ciphertext[size + 1];
int key = atoi(k);
for (int i = 0; i < size; i++)
{
if (isalpha(plaintext[i]))
{
encipher(key, i, &ciphertext[i], plaintext);
}
else
{
ciphertext[i] = plaintext[i];
}
}
ciphertext[size] = '\0';
printf("%s\n", ciphertext);
}
The program was called csr13, and gives the following outputs:
$ csr13 4
The Quick Brown Fox Jumped Over The Lazy Dog
Xli Uymgo Fvsar Jsb Nyqtih Sziv Xli Pedc Hsk
$ csr13 22
Xli Uymgo Fvsar Jsb Nyqtih Sziv Xli Pedc Hsk
The Quick Brown Fox Jumped Over The Lazy Dog
$
A better design for the encipher function would pass the single character plus the 'key' offset and would return the encrypted character:
#include <assert.h>
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
static bool isNumeric(string k, int size)
{
for (int i = 0; i < size; i++)
{
if (!isdigit((unsigned char)k[i]))
return false;
}
return true;
}
static int encipher(int k, int c)
{
assert(isalpha(c));
if (islower(c))
return (c - 'a' + k) % 26 + 'a';
else
return (c - 'A' + k) % 26 + 'A';
}
int main(int argc, string argv[])
{
string k = argv[1];
if (argc < 2 || !isNumeric(k, strlen(k)))
return 1;
string plaintext = GetString();
int size = strlen(plaintext);
char ciphertext[size + 1];
int key = atoi(k);
for (int i = 0; i < size; i++)
{
if (isalpha(plaintext[i]))
ciphertext[i] = encipher(key, plaintext[i]);
else
ciphertext[i] = plaintext[i];
}
ciphertext[size] = '\0';
printf("%s\n", ciphertext);
}

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;
}

How to divide a string to substring and assign another substring?

I want to divide *eString to substrings. Substrings should be like that:
y_{1} = y_{1}y_{m+1}y_{2m+1}...
y_{2} = y_{2}y_{m+2}y_{2m+2}...
y_{m} = y_{m}y_{2m}y_{3m}...
where y is the element of *eString, and y is the substring of these elements.
For instance, if an user expects the key length which is 5, there should be (string size / 5) substrings. y_{1} has to contain the fist element of each divided substring. So, how can I implement this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ALPHA 26
char *ReadFile(char *);
int main(int argc, char *argv[])
{
double frequency[ALPHA] = {0};
int c = 0;
int keylen = 0;
int counter = 0;
double indexofCoincidence = 0,total = 0;
const char *eString = ReadFile("cipher.txt");
int len = 0;
if (eString) {
puts("The encrypted text is:");
puts(eString);
puts("");
len = strlen(eString);
printf("The length of text is %d\n",len);
}
puts("");
while(eString[c]!= '\0'){
if(eString[c]>= 'a' && eString[c]<='z')
frequency[eString[c]-'a']++;
c++;
}
puts("The letters frequencies are :\n");
for(c=0; c<ALPHA;c++){
if(frequency[c]!= 0)
printf("%c : %.3f\t",c+'a',(frequency[c]/len));
total += (frequency[c]*(frequency[c]-1));
}
indexofCoincidence = (total/((len)*(len-1)));
printf("\n\nIndex of Coincidence : %.3f\n",indexofCoincidence);
if(indexofCoincidence < 0.060){
printf("\nIt looks like randomly.\n");
}
printf("Enter the your expected key length : ");
scanf("%d",keylen);
printf("\n");
char *y;
while(counter != keylen)
{
for(int i = 0; i<(len/keylen);i++){
y[counter] = *eString();
}
counter++
}
return EXIT_SUCCESS;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
char *eString = "The quick brown fox jumps over the lazy dog";
int keylen = 5;
int len = strlen(eString);
int y_len = (len + keylen) / keylen + 1;
int i,j;
char **y = malloc(keylen * sizeof(*y));
for(i=0; i < keylen; ++i){
y[i] = malloc(y_len * sizeof(**y));
}
char *p = eString;
i = j = 0;
while(*p){
y[i % keylen][j] = *p++;
y[i % keylen][j+1] = 0;
if(++i % keylen == 0)
++j;
}
//check print & deallocate
for(i = 0; i < keylen; ++i){
printf("y_{%d} : %s\n", i+1, y[i]);
free(y[i]);
}
free(y);
return 0;
}

Caesars Cipher in C

In this caesars cipher code how do i make it so that it reads in spaces, special characters (!##$*...), and numbers and keeps them as they are and prints them? Also i put an fprintf(file2,"\n") at the end of the fgets while loop and it does start a new line but it always prints a weird character at the end of the previous line.
#include <stdio.h>
int main (int argc, char *argv[]) {
char caesar[256];
int shift;
FILE *file1=fopen(argv[1],"r");
FILE *file2=fopen(argv[2],"w");
sscanf(argv[3], "%d", &shift);
while(fgets(caesar,sizeof(caesar),file1)!=NULL){
int i = 0;
while (caesar[i] != '\0') {
if (((caesar[i] + shift) >= 65 && (caesar[i] + shift) <= 90)||((caesar[i] + shift) >= 97 && (caesar[i] + shift) <= 122)) {
caesar[i] += (shift);
}
else {
caesar[i] += (shift - 26);
}
i++;
}
fprintf(file2,"%s", caesar);
fprintf(file2,"\n");
}
return 0;
}
#include <stdio.h>
#include <ctype.h>
int main (int argc, char *argv[]) {
char caesar[256];
int shift;
FILE *file1=fopen(argv[1],"r");
FILE *file2=fopen(argv[2],"w");
sscanf(argv[3], "%d", &shift);
while(fgets(caesar,sizeof(caesar), file1)!=NULL){
char ch;
int i = 0;
for(i = 0; (ch=caesar[i]) != '\0'; ++i) {
if (isalpha(ch)) {//Only alphabet
char a, z;
if(isupper(ch)){
a = 'A'; z = 'Z';
} else {
a = 'a'; z = 'z';
}
caesar[i] += shift;//this depend on the sequence of character codes.
if(caesar[i] > z){
caesar[i] = a + caesar[i] - z - 1;
}
}
}
fprintf(file2, "%s", caesar);
}
return 0;
}

Strange unwanted three digit code printouts from caesar cipher

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.

Resources