Home > Blockchain >  C Programming - How to change every occurrence of character in a string with another character
C Programming - How to change every occurrence of character in a string with another character

Time:11-26

The task is for the user to insert a string and the program will output a secret message, that changes each occurrence of a character of that string with another character. The list of new characters that will be inserted are given by the permutation "qjczieaungsdfxmphybklortvw", which correspond to every letter of the alphabet. So for example, the string "abcxyz" will return "qjctvw". The program will ignore symbols and capital letters, so "Abc" will become "Ajc".

I tried to achieve this by comparing each position of the string with each letter of the alphabet. If it matches, then that position of the string will be replaced by the position of the secret permutation that is the same as the position of the traditional alphabet (since they correspond). The code technically works, but I'm not getting the right values. For instance, for every "a" I should get a "q", but I'm returned a "h". If anyone can fix my code, it will be greatly appreciated. CODE BELOW: PLEASE COPY AND PASTE INTO YOUR PREFFERED CODE EDITOR TO SEE WHAT I MEAN BY RETURNING THE WRONG VALUES.

#include <string.h>
#define MAX_STR_LEN 256
int main(void)
{
  char perm[] = "qjczieaungsdfxmphybklortvw";
  char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
  int i, j;
  char msg[MAX_STR_LEN 1];

  /* read the message from the terminal using fgets. The variable msg will contain the message. */
  fgets(msg, MAX_STR_LEN, stdin);

/*compares each value of the string to the alphabet*/
  for (i = 0; i < (strlen(msg) - 1); i  ) {
    for (j = 0; j < (strlen(alphabet) - 1); j  ) {
       if (msg[i] == alphabet[j]) {msg[i] = perm[j];}
     }
  }
  printf("%s", msg);
}

CodePudding user response:

For starters after the call of fgets

fgets(msg, MAX_STR_LEN, stdin);

you need to remove the new line character '\n' that can be appended to the entered string by the function.

msg[ strcspn( msg, "\n" ) ] = '\0';

Also the for loops are incorrect.

At least instead of using the condition

j < (strlen(alphabet) - 1)

in the inner for loop

 for (j = 0; j < (strlen(alphabet) - 1); j  ) {
   if (msg[i] == alphabet[j]) {msg[i] = perm[j];}
 }

you need to use the condition

j < strlen(alphabet)

and when a character is found in the string alphabet you have to exit the loop. Otherwise the already changed character can be changed the second time.

You can use the function strchr instead of the manually written inner for loop. For example

/*compares each value of the string to the alphabet*/
for ( size_t i = 0; msg[i] != '\0';  i   ) 
{
    const char *p = strchr( alphabet, msg[i] );

    if ( p != NULL )
    {
        msg[i] = perm[p - alphabet];
    }
}

Here is your updated program.

#include <stdio.h>
#include <string.h>

#define MAX_STR_LEN 256

int main( void )
{
    const char *perm= "qjczieaungsdfxmphybklortvw";
    const char *alphabet= "abcdefghijklmnopqrstuvwxyz";
    char msg[MAX_STR_LEN 1];
    
    /* read the message from the terminal using fgets. The variable msg will contain the message. */
    fgets( msg, MAX_STR_LEN, stdin );
    
    msg[ strcspn( msg, "\n" ) ] = '\0';
    
    /*compares each value of the string to the alphabet*/
    for ( size_t i = 0; msg[i] != '\0';  i   ) 
    {
        const char *p = strchr( alphabet, msg[i] );

        if ( p != NULL )
        {
            msg[i] = perm[p - alphabet];
        }
    }
    
    puts( msg );
}

If to enter the string

abcxyz

then the program output is

qjctvw

CodePudding user response:

This task can be very easy once you get to the root of the problem and observe that:

  1. Your alphabet replacements string is just a simple array having letter values mapped to indexes from 0 to 25.
  2. Characters themselves have some integer values specified by the ASCII standard, and they happen to be conscutive ('b'=='a' 1).

Having this knowledge, we can invent a function that takes a character and converts it to the correct position in the perm string. We can do that in a extremely simple manner, by just subtracting 'a' from whatever character we have. 'a'-'a' will be equal to 0, and so on.

This can be implemented as a function like this: (or you can just inline it, since it's pretty trivial)

int get_char_index(char c){
    return c - 'a';
}

And now, having access to this function, all we need to do is to iterate over a string character by character (for loop, while loop, doesn't matter), read the char from the string, feed it to the function, and then once you get the corresponding index of the perm, you just need to assign the value of char under that index back to the string.

int main() {
    const char perm[] = "qjczieaungsdfxmphybklortvw";
    
    char some_string_to_convert[] = "aabbccddeeffgghhiijjkkllmmnnoopprrssttqqvvwhatever";
    for(int i=0; i<strlen(some_string_to_convert); i  ){
        char c = some_string_to_convert[i];
        int perm_index = get_char_index(c);
        some_string_to_convert[i] = perm[perm_index];
    }

    printf("%s", some_string_to_convert);
}

The following code outputs: qqjjcczziieeaauunnggssddffxxmmppyybbkkhhooruqkioiy

I hope my answer helps you solve the problem.

  • Related