I am trying to write a function that takes in variables cipher, userinput, alphabet and outputs the replace letters. for example at execution it takes in an argument argv ZYXWVUTSRQPONMLKJIHGFEDCBA. requests a user to input anything then switches only the letters for example input aBc should output zYx
// function that takes in cipher(c), userinput(u) and alphabet(a) and outputs cipher text
void cipher_text(string c, string u, string a)
{
string result = u;
for (int i = 0; i < strlen(u); i )
{
for (int k = 0; k < strlen(a); k )
{
if (tolower(u[i]) == a[k])
{
if(islower(u[i]))
{
result[i] = tolower(c[k]);
printf("%s %s\n",result,c);
}
else
{
result[i] = toupper(c[k]);
}
}
}
}
// printf("ciphertext: %s\n", result);
}
with cipher as YUKFRNLBAVMWZTEOGXHCIPJSQD and userinput as abcd I was expecting yukf but got qidc
CodePudding user response:
The problem of the function is this inner for loop
for (int k = 0; k < strlen(a); k )
{
if (tolower(u[i]) == a[k])
{
if(islower(u[i]))
{
result[i] = tolower(c[k]);
printf("%s %s\n",result,c);
}
else
{
result[i] = toupper(c[k]);
}
}
}
You need to break it as soon as a letter is found in the string pointed to by the pointer a. Otherwise there can be a chain of changes.
Also using the function strlen is inefficient and redundant.
Instead of the for loop you could use standard function strchr.
The function can be declared and defined the following way
string cipher_text( string c, string u, string a )
{
for ( string p = u; *p != '\0'; p )
{
string pos = strchr( a, tolower( ( unsigned char )*p ) );
if ( pos != NULL )
{
size_t i = pos - a;
*p = islower( ( unsigned char )*p )
? tolower( c[i] )
: c[i];
}
}
return u;
}
Pay attention to that instead of the typedef name string it is better to use its underlaying type char *.
In this case the function can look the following way as shown in the demonstration program below.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char * cipher_text( const char *c, char *u, const char *a )
{
for (char *p = u; *p != '\0'; p )
{
const char *pos = strchr( a, tolower( ( unsigned char )*p ) );
if (pos != NULL)
{
size_t i = pos - a;
*p = islower( ( unsigned char )*p )
? tolower( c[i] )
: c[i];
}
}
return u;
}
int main( void )
{
const char *c = "XYZ";
const char *a = "abc";
char u[] = "c_B_a";
puts( cipher_text( c, u, a ) );
}
The program output is
z_Y_x
