Caesar Cipher Algorith Shifting C [closed] - c

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
So I was writing a C program to make use of caesar algorithm using a custom table, where I will give the table and shifting will be done using that table e.g the text "abc" according to table "abc" with key=1 should be ciphered as bca, however i am having difficulty on the last characters if key+index of letter is higher than the length of the table stored here is my code
void encrypt (char table[],char entext[],char text[],int key)
{
int i,j;
int k = strlen(table);
//int result = (key + k);
for (i=0;i<strlen(table);++i)
{
j = 0;
if (text[i]!='\0')
{
while (text[i]!=table[j])
{
j++;
}
if ((j+key)>k)
{
j=(j+key)%k;
//j = (result - j);
}
else
j = j + key;
entext[i] = table[j];
}
}
entext[i+1] = '\0';
puts(entext);
}
int main()
{
char table[100] , text[100] , entext[100] , c;
int i , j , key;
printf("Enter the text : ");
gets(text);
printf("Enter the table : ");
gets(table);
printf("Enter the key : ");
scanf("%d",&key);
encrypt(table,entext,text,key);
system("pause");
return 0;
}

if ((j+key)>k)
should be
if ((j+key)>=k)
Besides, this check is completely unnecessary because of how mod works. I will take the liberty to rewrite your code so it looks nicer:
void encrypt (char table[],char entext[],char text[],int key)
{
int i,j;
int k = strlen(table);
//int result = (key + k);
for (i=0;i<strlen(table);++i)
{
if (text[i]!='\0')
{
for(j=0; text[i] != table[j] ;j++);
entext[i] = table[(j+key)%k];
}
}
entext[i+1] = '\0';
puts(entext);
}
I believe you could make this "table" lookup more efficient by indexing the value of the char itself, but unless you are dealing with pretty big input, this won't really make a difference.

void encrypt (char table[], char entext[], char text[], int key) {
int i,j;
int k = strlen(table);
for (i=0;text[i];++i){
for(j=0;table[j] && text[i]!=table[j];++j)
;
if(table[j]=='\0')//character not find at table
entext[i] = text[i];//Not slide. // or Error?
else {
j += key;
if(j>=k)
j -= k;//j = j % k
entext[i] = table[j];
}
}
entext[i] = '\0';
puts(entext);
}

Related

Why is my %d specifier putting the "-" after the number? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed last month.
Improve this question
I am trying to make a C implementation of the printf function. Why does my %d specifier return
+2048 - 0 - 1337-!
instead of
-2048 - 0 - -1337!
when I run
int main() {
int ret_val = my_printf("%d - %d - %d!\n", 2048, 0, -1337);
return ret_val;
}
This is my %d specifier code
{
int value = va_arg(args, int);
char buffer[32];
int index = 0;
if (value < 0)
{ //Repair this
buffer[index++] = '-';
value = -value;
}
if (value == 0)
{
buffer[index++] = '0';
}
else
{
while (value > 0)
{
buffer[index++] = '0' + (value % 10);
value /= 10;
}
}
for (int i = 0; i < index / 2; i++)
{
char temp = buffer[i];
buffer[i] = buffer[index - i - 1];
buffer[index - i - 1] = temp;
}
write(1, buffer, index);
size += index;
break;
}
I have tried switching these 2 lines with each
The reason for the symptoms reported by the OP has been quickly and correctly addressed by #EricPostpischil in the comments section.
The problem with writing code from the wrong perspective is that one winds up writing far too much code. Then, lost in the fog of verbose code, patches and bandages are applied that don't quite fulfil the need.
Simply fill the 32-byte buffer from right to left, prefix the minus sign if necessary, and write the correct number of bytes to the output.
int val = va_arg( args, int );
int absVal = abs(val);
char buf[ 32 ];
int i = sizeof buf;
do buf[--i] = (char)('0' + (absVal%10)); while((absVal/= 10) > 0);
if( val < 0 )
buf[--i] = '-';
write( 1, buf + i, sizeof buf - i );
No muss, no fuss trying to reverse the array... or most of it...

Search a Word in a 2D characters array [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Given a 2D array of size 100 x100 of characters and a word (1D character array), find the occurrences of given word in 2D array (search only left to right horizontally).
char data[100][100] =
{
"ACFRTBOOK",
"BOPNBOOKQUIZGEEK",
"IDEQAPRACTICE"
};
char Word[4] = "BOOK";
Output:
pattern found at 0, 5
pattern found at 1, 4
This might help:
int k = 0, n = 0;
char word[] = "BOOK";
for (int i = 0; i < size - 1; i++)
{
for (int j = 0; data[i][j] != '\0'; j++)
{
n = j;
while (data[i][n] == word[k] && word[k] != '\0')
{
n++;
k++;
if (word[k] == '\0')
{
printf("Found at %i, %i", i, j)
}
}
k = 0;
}
}
Firstly, you cannot initialize a char array as a String like you did with char Word[4] = "BOOK"; this would have to be char word[4] = {'b','o','o','k'}; The same applies to your 2D array named data.
So here is how you would do such a thing. I added in //comments to explain, but the general idea is to turn the arrays into Strings as these are easier to use when locating another set of characters.
Please let me know if you need further assistance. I hope this helps.
public void findWord(char[] word; char[][] data){
String w = new String(word); //it is much easier to work with strings for a searching problem like this
int x=0,y=0;
for(char[] i:data){//iterates through each row of data
String d = new String(i);
while(d.contains(w)){
x+=i.indexOf(w);//locates the pattern
System.out.println("pattern found at " + x + ", " + y);
x++;
d=s.substring(x);//this removes the previous occurance of the patern so that the index of can find a new repeat in the same row
}
y++;
x=0;//reset for next array
}
}

Intro to Programming in C - [Final Exam Sample] Palindrome Function [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I need help! I can't do it. I tried in many ways but non has worked.
At least can someone help me with the LOGIC. Below I will paste my code.
Develop a program with a function that receives an array of chars. The function has to modify the original and copy it exactly to another one but putting two asterisks (**) before each word that is a PALINDROME, a palindrome is a word which reads the same backward or forward (e.g ANNA, KAYAK).
For example,
my best friend anna has a red kayak
my best friend **anna has a red **kayak.
#include <stdio.h>
#include <stdlib.h>
void Cargar(char texto1[])
{
int i=0;
char letra;
do
{
letra=getche();
if(letra != '.')
{
texto1[i]=letra;
i++;
}
}
while (letra != '.' && i<99);
texto1[i]='\0';
}
int main()
{
char texto1[100], texto2[100];
printf("Ingrese texto: ");
Cargar(texto1);
int pos=0, esp_anterior=0, aux1=0, aux2=0, aux3=0, bandera=0;
int i, j, k;
for(pos = 0 ; texto1[pos] != '\0' ; pos++)
{
if( texto1[pos] == ' ')
{
if(bandera==0)
{
if( hay_palindromo(texto1, pos, esp_anterior) == 1)
{
texto2[0]='*';
texto2[1]='*';
for(i=2, j=0; j<pos ; j++ , i++)
{
texto2[i]=texto1[j];
}
aux1=i;
aux2=j;
}
else
{
for(i=0; i<pos; i++)
{
texto2[i]=texto1[i];
}
aux3=i;
}
bandera = 1;
esp_anterior = pos;
}
else
{
if(bandera == 1)
{
if( hay_palindromo(texto1, pos, esp_anterior) == 1)
{
texto2[aux1]='*';
texto2[aux1+1]='*';
for(i=aux1+2, j=aux2; j<pos ; j++ , i++)
{
texto2[i]=texto1[j];
}
aux1=i;
aux2=j;
}
else
{
for(i=aux3; i<pos; i++)
{
texto2[i]=texto1[i];
}
aux3=i;
}
esp_anterior=pos;
}
}
}
}
printf("\n%s", texto2);
return 0;
}
int hay_palindromo(char texto1[], int pos, int esp_anterior)
{
int i, j, bandera=0;
for(i=esp_anterior, j=pos; i<pos; i++, j--)
{
if(texto1[i] == texto1[j])
{
bandera=1;
}
else
{
bandera=0;
break;
}
}
if(bandera==1)
{
return 1;
}
else
{
return 0;
}
}
I would suggest a logic like that:
Take string, separate it by a delimiter - " " (space) in your case with strtok.
Then, send each delimited word to a function that determines whether the string is a palindrome or not.
If the string is palindrome, allocate enough space for the string + "", and copy "" + string into the allocated space, save the current position of your 'cursor' on that array.
Pseudo Example:
"Anna notpali"
char *new_str;
int cursor = 0;
is_palindrome("Anna")
Yes -> new_str = malloc(strlen("Anna") + strlen("**") + 1)
strcpy(&(new_str[cursor]),"**Anna");
cursor += strlen("**Anna");
is_palindrom("notpali")
No -> new_str = realloc(new_str,strlen(" notpali") + 1)
strcpy(&(new_str[cursor])," notpali");
cursor += strlen(" notpali");
// After going through all the words
new_str[cursor] = '\0'
etc, there might be some corner cases to take care of, but this is a basic logic I suggest to approach it.

Reduce amount of C code [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
How can I refactor this with less code?
This is homework and is cracking a Caesar cipher-text using frequency distribution.
I have completed the assignment but would like it to be cleaner.
int main(int argc, char **argv){
// first allocate some space for our input text (we will read from stdin).
char* text = (char*)malloc(sizeof(char)*TEXT_SIZE+1);
char textfreq[ALEN][2];
char map[ALEN][2];
char newtext[TEXT_SIZE];
char ch, opt, tmpc, tmpc2;
int i, j, tmpi;
// Check the CLI arguments and extract the mode: interactive or dump and store in opt.
if(!(argc == 2 && isalpha(opt = argv[1][1]) && (opt == 'i' || opt == 'd'))){
printf("format is: '%s' [-d|-i]\n", argv[0]);
exit(1);
}
// Now read TEXT_SIZE or feof worth of characters (whichever is smaller) and convert to uppercase as we do it.
for(i = 0, ch = fgetc(stdin); i < TEXT_SIZE && !feof(stdin); i++, ch = fgetc(stdin)){
text[i] = (isalpha(ch)?upcase(ch):ch);
}
text[i] = '\0'; // terminate the string properly.
// Assign alphabet to one dimension of text frequency array and a counter to the other dimension
for (i = 0; i < ALEN; i++) {
textfreq[i][0] = ALPHABET[i];
textfreq[i][1] = 0;
}
// Count frequency of characters in the given text
for (i = 0; i < strlen(text); i++) {
for (j = 0; j < ALEN; j++) {
if (text[i] == textfreq[j][0]) textfreq[j][1]+=1;
}
}
//Sort the character frequency array in descending order
for (i = 0; i < ALEN-1; i++) {
for (j= 0; j < ALEN-i-1; j++) {
if (textfreq[j][1] < textfreq[j+1][1]) {
tmpi = textfreq[j][1];
tmpc = textfreq[j][0];
textfreq[j][1] = textfreq[j+1][1];
textfreq[j][0] = textfreq[j+1][0];
textfreq[j+1][1] = tmpi;
textfreq[j+1][0] = tmpc;
}
}
}
//Map characters to most occurring English characters
for (i = 0; i < ALEN; i++) {
map[i][0] = CHFREQ[i];
map[i][1] = textfreq[i][0];
}
// Sort the map lexicographically
for (i = 0; i < ALEN-1; i++) {
for (j= 0; j < ALEN-i-1; j++) {
if (map[j][0] > map[j+1][0]) {
tmpc = map[j][0];
tmpc2 = map[j][1];
map[j][0] = map[j+1][0];
map[j][1] = map[j+1][1];
map[j+1][0] = tmpc;
map[j+1][1] = tmpc2;
}
}
}
if(opt == 'd'){
decode_text(text, newtext, map);
} else {
// do option -i
}
// Print alphabet and map to stderr and the decoded text to stdout
fprintf(stderr, "\n%s\n", ALPHABET);
for (i = 0; i < ALEN; i++) {
fprintf(stderr, "%c", map[i][1]);
}
printf("\n%s\n", newtext);
return 0;
}
Um, Refactoring != less code. Obfuscation can sometimes result in less code, if that is your objective :)
Refactoring is done to improved code readability and reduced complexity. Suggestions for improvement in your case:
Look at the chunks of logic you've implemented and consider replacing them with in built functions is usually a good place to begin. I'm convinced that some of the sorting you've performed can be replaced with qsort(). However, side note, if this is your assignment, your tutor may be a douche and want to see you write out the code in FULL VS using C's in built function, and dock you points on being too smart. (Sorry personal history here :P)
Move your logical units of work into dedicated functions, and have a main function to perform orchestration.

How to find whether the string is a Lapindrome? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 years ago.
Improve this question
The following code is giving correct output as given on the codechef problem page: http://www.codechef.com/problems/LAPIN
but getting wrong answer on submission
please tell me the possible problem with my code
here is the question
Lapindrome is defined as a string which when split in the middle, gives two halves having the same characters and same frequency of each character. If there are odd number of characters in the string, we ignore the middle character and check for lapindrome. For example gaga is a lapindrome, since the two halves ga and ga have the same characters with same frequency. Also, abccab, rotor and xyzxy are a few examples of lapindromes. Note that abbaab is NOT a lapindrome. The two halves contain the same characters but their frequencies do not match.
Your task is simple. Given a string, you need to tell if it is a lapindrome.
Input:
First line of input contains a single integer T, the number of test cases.
Each test is a single line containing a string S composed of only lowercase English alphabet.
Output:
For each test case, output on a separate line: "YES" if the string is a lapindrome and "NO" if it is not.
and here is the code
#include<stdio.h>
#include<string.h>
int main()
{
int f,t,mid,len;
char arr[1000];
int left[125],right[125];
scanf("%d",&t);
for(int i=0;i<t;i++)
{
f=0;
scanf("%s",arr);
memset(left,0,sizeof(left));
memset(right,0,sizeof(right));
len=strlen(arr);
for(int i=0;i<len/2;i++)
left[arr[i]]++;
for(int i=(len+1)/2;i<len;i++)
right[arr[i]]++;
for(int i=0;i<strlen(arr);i++)
{
if(left[arr[i]]!=right[arr[i]])
f++;
break;
}
if(f==0)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
I recommend you read up on modularity; it'll make your life easier.
#include <stdio.h>
#define BOOL unsigned char
#define TRUE 1
#define FALSE 0
unsigned string_length(char *string)
{
unsigned counter = 0;
while (string[counter++] != '\0') { }
return counter - 1;
}
BOOL are_equal(unsigned *a, unsigned *b, int size)
{
int i;
for (i = 0; i < size; ++i)
{
if (a[i] != b[i])
{
return FALSE;
}
}
return TRUE;
}
BOOL is_lapindrome(char *string)
{
unsigned left[26] = { 0 }, right[26] = { 0 },
str_len = string_length(string);
if (str_len < 2)
{
return FALSE;
}
int i;
for (i = 0; i <= str_len / 2 - 1; ++i)
{
left[string[i] - 'a']++;
}
for (i = (str_len + 1) / 2; i < str_len; ++i)
{
right[string[i] - 'a']++;
}
return are_equal(left, right, 26);
}
int main()
{
char *list[6] =
{
"gaga",
"abcde",
"rotor",
"xyzxy",
"abbaab",
"ababc"
};
int i;
for (i = 0; i < 6; ++i)
{
printf("%s\n", is_lapindrome(list[i]) == TRUE ? "YES" : "NO");
}
return 0;
}
Your buffer is one byte too short - a string of 1000 characters requires 1001 chars, the last one taken by the nul terminator.
"lowercase English alphabet" sounds a bit ambiguous - I'd say that by some interpretation, it could contain spaces. If so, the input will be read incorrectly.
I can't see other problems right now, but I'd strongly suspect the first one.

Resources