Home > Net >  why is my function encodeChar does not work?
why is my function encodeChar does not work?

Time:11-04

The code below is supposed to allow the user to enter two character strings s and t, an array of structures and the size of array as parameters, encodes the characters in s to t, and passes the encoded string t to the caller via call by reference. I cannot understand why my function encodeChar is wrong. I have already tried to use the indexing method and it is similar to the correct answer. But when i input

1
3
a
b
b
c
c
d
3
abcd
4

, the output is abdd. I do not understand where is my mistake. Please have me resolve my misconceptions.

#include <string.h>
typedef struct {
   char source;
   char code;
} Rule;
void createTable(Rule *table, int *size);
void printTable(Rule *table, int size);
void encodeChar(Rule *table, int size, char *s, char *t);
int main() 
{
   char s[80], t[80], dummychar, *p;
   int size, choice;
   Rule table[100];
     
   printf("Select one of the following options:\n");
   printf("1: createTable()\n");     
   printf("2: printTable()\n");
   printf("3: encodeChar()\n");      
   printf("4: exit()\n");    
   do {
      printf("Enter your choice: \n");
      scanf("%d", &choice);  
      switch (choice) {
         case 1:           
            printf("createTable(): \n");
            createTable(table, &size);           
            break;               
         case 2:           
            printf("printTable(): \n");
            printTable(table, size);           
            break;               
         case 3:       
            scanf("%c",&dummychar);
            printf("Source string: \n");
            fgets(s, 80, stdin);  
            if (p=strchr(s,'\n')) *p = '\0'; 
            encodeChar(table,size,s,t);
            printf("Encoded string: %s\n", t);   
            break;   
         default: 
            break;
      } 
   } while (choice < 4);
   return 0;
}
void printTable(Rule *table, int size)
{
   int i;

   for (i=0; i<size; i  )
   {
      printf("%d: %c->%c\n", i 1, table->source, table->code);
      table  ;
   }
}
void createTable(Rule *table, int *size)
{
    /*edit*/
    /* Write your code here */
    /*edit*/
    /* Write your code here */
    int i;
    char dummy[80];
    printf("Enter number of rules: \n");
    scanf("%d", size); // dont careless here 
    for(i=0; i< *size; i  ){
        printf("Enter rule %d: \n", i 1);
        fgets(dummy, 80,stdin); // why need to use this twice 
        printf("Enter source character: \n");
        scanf("%c", &table[i].source);    
        fgets(dummy,80,stdin);// why 
        printf("Enter code character: \n ");
        scanf("%c", &table[i].code);
    }
    /*end_edit*/
    /*end_edit*/
}
void encodeChar(Rule *table, int size, char *s, char *t) 
{
    /*edit*/
    /* Write your code here */// this is wrong
    int i, j;
    for(i = 0 ; s[i] != '\0'; i  ){
        for(j = 0; j < size; j  ){
            if(s[i] == table[j].source){
                *t = table[j].code;
            }
            else{
                *t = s[i];
            }
        }
        t  ;
    }
    *t = '\0';

        /*edit*/
    /* this is correct 
    int i;
    while(*s!='\0'){
        for(i = 0; i < size; i  ){

        if(*s != table[i].source)
            *t = *s;
        else
            *t = table[i].code;
       t  ;
       s  ;
        }
    }
    *t = '\0';
    
    */
}

CodePudding user response:

Here a paper sheet and a pencil would be enough.

Just follow your code for abcd. The relevant part is

for(i = 0 ; s[i] != '\0'; i  ){
    for(j = 0; j < size; j  ){
        if(s[i] == table[j].source){
            *t = table[j].code;
        }
        else{
            *t = s[i];
        }
    }
    t  ;
}
*t = '\0';

Let's go:

  • i is 0, s[i] is a

    • j is 0, table[j].source is a: *t receives b
    • j is 1, table[j].source is b: *t recieves (back) a !...

Only the last rule can be applied with your code...

A simple fix would be to break out of the loop when a rule is applied to prevent the following ones to roll back the change:

for(i = 0 ; s[i] != '\0'; i  ){
    for(j = 0; j < size; j  ){
        if(s[i] == table[j].source){
            *t = table[j].code;
            break;      // do not examine other rules
        }
        else{
            *t = s[i];
        }
    }
    t  ;
}
*t = '\0';

But if the same character is changed by multiple rules, this code would use the first one, while the correct code would use the last one, so this would be more consistent:

for(i = 0 ; s[i] != '\0'; i  ){
    for(j = size-1; j >= 0; j--){  // examine rules in descending order
        ...

Anyway, there are still possible improvements here, so you could probably post it to CodeReview for advices for best practices...

  • Related