简体   繁体   中英

C program doesn't work correctly

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


void main()
{
    char alfavita[30] =
    {
        'a',
        'b',
        'c',
        'd',
        'e',
        'f',
        'g',
        'h',
        'i',
        'j',
        'k',
        'l',
        'm',
        'n',
        'o',
        'p',
        'q',
        'r',
        's',
        't',
        'u',
        'v',
        'w',
        'x',
        'y',
        'z'
    };

    char str[20];


    printf("Give a word:\n");
    gets(str);


    for(int i=0;i<strlen(str);i++)
    {
        for(int j=0;j<strlen(alfavita);j++)
            if(alfavita[j] == str[i])
                str[i] = alfavita[j+3];
    }



    puts(str);
}

For example if i give 'a' it should be return 'd' (each letter will transform into the 3d next of the alfavita array ) But it just prints me a null string. I can't find something wrong or I don't see it .

str[i] = alfavita[j+3];
After this line the code continues, so it will put i+3, i+6, ... until it gets out of alfavita.
You can add a break to exit the inner loop like that:

for(int i=0;i<strlen(str);i++)    
{
    for(int j=0;j<strlen(alfavita);j++)
        if(alfavita[j] == str[i])
        {
            str[i] = alfavita[j+3];
            break;  // next i.
        }
}

, or maybe just directly access the array:

for(int i=0;i<strlen(str);i++)
{
  char c = str[i];
  if (c >= 'a' && c <= 'z') {
    str[i] = alfavita[(c - 'a' + 3) % strlen(alfavita)];
  }
}

Note the % strlen(alfavita) to avoid ending after the end of the list. You could also write it:

if (c >= 'a' && c <= 'z') {
  str[i] = ((c - 'a' + 3) % 26) + 'a';
}

You can use a table that gives the replacement character for each character.

Then encode by computing the index into plain , and transferring that index into encoded :

char encode_char(char c)
{
  const char *plain   = "abcdefghijklmnopqrstuvwxyz";
  const char *encoded = "defghijklmnopqrstuvwxyzabc";

  const char *pp = strchr(plain, c);
  if(pp != NULL)
    return encoded[(ptrdiff_t) (pp - plain)];
  return '?';
}

How the above works:

  1. Define two strings that are supposed to be 1:1 mapped, ie plain[0] is encoded into encoded[0] . This can be more clearly modelled (ie by a struct that has the pair) but then the iniialization becomes more complicated.
  2. Search for the input character c inside the plain string. This returns NULL if not found, or a pointer to somewhere inside plain found.
  3. Make sure the pointer isn't NULL before using its value.
  4. Subtract plain (ie &plain[0] , the address of the a ) from pp . This evaluates to 0 for a , 1 for b , and so on.
  5. Use the computed index to look up the corresponding character in encoded .
  6. On failure to encode, return ? .

In a portable, general program, you can not use plain subtraction (ie c - 'a' ), since C does not guarantee that characters are encoded in values next to each other.

As pointed out, the above assumes that each character encodes in exactly one char . That might not be true for targets with exotic encodings, in which case it really is safer to use an explicit table, like this:

const struct {
  char plain;
  char encoded;
} encoding[] = {
 { 'a', 'd' },
 { 'b', 'e' },
 { 'c', 'f' },
 /* ... and so on ... */
};

The encoding function then becomes:

char encode_char2(char c)
{
  for(size_t i = 0; i < sizeof encoding / sizeof *encoding; ++i)
  {
    if(encoding[i].plain == c)
      return encoding[i].encoded;
  }
  return '?';  /* Not found. */
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM