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