0

I need to change a specified characters eg: a->z, d->b in a string. for eg: input is abandoned; output is zbznboneb. This is my code.

typedef struct {
    char source;
    char code;
} Rule;

void encodeChar (Rule table[5], char *s, char *t);

int main ()
{
    char s[80], t[80];
    Rule table[5] = { 'a', 'd', 'b', 'z', 'z', 'a', 'd', 'b', '\0', '\0'
    };

    printf ("Source string: \n");
    gets (s);
    encodeChar (table, s, t);
    printf ("Encoded string: %s\n", t);
    return 0;
}

void encodeChar (Rule table[5], char *s, char *t)
{
    int j = 0;

    while (s[j] != '\0') {
        if (s[j] == 'a')
            putchar ('d');
        if (s[j] == 'b')
            putchar ('z');
        if (s[j] == 'z')
            putchar ('a');
        j++;
    }
    return 0;
}

But it gives me output dz, only and does not return the whole word when, i type abandoned.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
skylight
  • 69
  • 10
  • Why do you think I get the feeling you're not reading a book? – autistic Sep 27 '17 at 03:15
  • I'll tell you why... 1/ this problem is so basic that people who *do* read books generally don't have it, 2/ it's the kind of question I see from people who *don't* read books more often than not, 3/ I see this kind of question dozens of times a day and 4/ **rather than asking such question one after another after another, you could save lots of time by reading a book** – autistic Sep 27 '17 at 03:17
  • 1
    If your book tells you to use `gets`, burn it now! Get a new book. `gets` has been removed from the C11 standard due to its insecurity, use `fgets` instead. – David C. Rankin Sep 27 '17 at 03:29
  • @DavidC.Rankin You know as well as I do, this person most likely *isn't using a book*... There's nothing to *burn*, though that doesn't change the fact that *it isn't working for him/her*. Look past the `gets` issue, and you'll see, this is a *very basic* problem people who read books won't possibly have. People who read books will ask about the book long before they try to write code like this... *if they need to*... – autistic Sep 27 '17 at 03:36
  • like [this](https://ideone.com/diaPYS) – BLUEPIXY Sep 27 '17 at 04:16
  • Thank you so much. trying to understanding what u have coded. is it possible for u to write comment beside the code? @BLUEPIXY – skylight Sep 27 '17 at 05:12

2 Answers2

0

If you'd be so kind as to explain where you output any character other than a, z or d within this code:

void encodeChar(Rule table[5], char *s, char *t)
{
    int j =0;

    while(s[j] != '\0')
    {
        if (s[j] == 'a')
            putchar('d');
        if (s[j] == 'b')
            putchar('z');
        if (s[j]=='z')
            putchar('a');
        j++;
    }
    return 0;
}

Please show me where you putchar anything but 'a', 'd' or 'z' and you'll get some strong hints towards the answer to your question.

P.S. Most importantly, if my rather educated guess was correct, YOU NEED A BOOK! You can't safely learn C without one. It's not theoretically impossible, but it is practically unlikely that you'll get it right without wasting heaps of time writing really unstable code.

I recommend K&R2E. It's not beginner friendly in the sense that it assumes you know some other programming concepts, but then again, C is not a beginner friendly language in the sense that you can't just mash your face against a keyboard and win.

If you're looking for something beginner friendly, choose a different language. C doesn't yet have any beginner friendly resources, or any reputable teachers that start from a beginner level, to the best of my knowledge.

If you're going to program in C, it is expected that you be able to read... books, manuals and error messages from compilers and valgrind all need the same kind of attention to detail that your code needs.

Anything you do manage to learn without a book, you're likely going to have to unlearn. So stop guessing immediately, start reading immediately and hopefully next time I hear from you it's not about something basic and explained by the book.

autistic
  • 1
  • 3
  • 35
  • 80
  • It may also be helpful to direct OP to the following link [**How to debug small programs**](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) and with the **note** to talk to the duck...`:)` – David C. Rankin Sep 27 '17 at 03:58
0

In addition to, and in agreement with, the other answer, there are fundamentals you are missing.

When you get into encodeChar, what parameter are you using to tell you how many elements table has? (you do want to iterate over each element in table checking table[i].source against each character to determine if a substitution is needed, right?)

note: C generally uses all lowercase for variable and function names while reserving all uppercase for constants and macros. C avoids the use of camelCase and MixedCase names -- leave those for C++ or java. While it is a matter of style, so it is largely up to you, it does say a lot about your appreciation for C, just like using gets does....

Don't use magic numbers in your code. If you need a constant, (e.g. 80), declare one at the top of your code, e.g.

#define MAXC 80   /* maximum characters for input buffer */

If you have multiple constants to declare, using an enum is an orderly way to declare global constants.

Using constants prevents having to pick through multiple array declarations to change their size. There is one convenient place up top to make the change.

Don't use gets, it is helpless against buffer overrun and has been removed from C11. Use fgets. All valid line-oriented input functions (e.g. fgets, and POSIX getline) read and include the trailing '\n' in the buffers they fill with input. Therefore, you need to trim the trailing newline from input, or you will have '\n' dangling off the end of any string you store that can cause problems with comparisons, etc.. Simply get the length and check character length - 1 to validate it is a '\n', then just overwrite it with a nul-terminating character ('\0' or 0, they are equivalent)

It's quite simple, e.g.:

len = strlen (s);                  /* get length of s   */
if (len && s[len - 1] == '\n')     /* check for \n      */
    s[--len] = 0;                  /* overwrite with \0 */

note: by using --len you now have the new length preserved in len.

Finally, for your encodechar function, you need to know how many elements of table you have. For each character in s you will compare it to each table[i].source if a match is found, then you will assign table[i].code to t and go to the next character. If not found, you will simply assign the character in s to t.

note: there is no need for the 5th element of table (e.g. '\0', '\0'), you can easily nul-terminate t without it -- and it is not a replacement.

Putting that together, you could write encodechar similar to the following:

void encodechar (rule *table, size_t sz, char *s, char *t)
{
    size_t i;

    while (*s) {                            /* for each character */
        int replaced = 0;                   /* replaced flag */
        for (i = 0; i < sz; i++)            /* for each element of table */
            if (*s == table[i].source) {    /* is char == table[i].source */
                *t = table[i].code;         /* replace it */
                replaced = 1;               /* set replaced flag */
                break;                      /* get next character */
            }
        if (!replaced)                      /* if not replaced */
            *t = *s;                        /* copy from s to t */
        s++, t++;                           /* increment s and t */
    }
    *t = 0;                                 /* nul-terminate t */
}

Putting it altogether, and noting main() is type int and therefore returns a value (See: C11 Standard §5.1.2.2.1 Program startup (draft n1570). See also: See What should main() return in C and C++?), you can do something similar to the following:

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

#define MAXC 80   /* maximum characters for input buffer */

typedef struct {
    char source;
    char code;
} rule;

void encodechar (rule *table, size_t sz, char *s, char *t);

int main (void) {

    char s[MAXC] = "", t[MAXC] = "";
    rule table[] = { {'a', 'd'}, {'b', 'z'}, {'z', 'a'}, {'d', 'b'} };
    size_t len = 0, n = sizeof table/sizeof *table;

    printf ("Source string : ");
    if (!fgets (s, MAXC, stdin)) {
        fprintf (stderr, "error: invalid input.\n");
        return 1;
    }

    len = strlen (s);                  /* get length of s   */
    if (len && s[len - 1] == '\n')     /* check for \n      */
        s[--len] = 0;                  /* overwrite with \0 */

    encodechar (table, n, s, t);

    printf ("Encoded string: %s\n", t);

    return 0;
}

void encodechar (rule *table, size_t sz, char *s, char *t)
{
    size_t i;

    while (*s) {                            /* for each character */
        int replaced = 0;                   /* replaced flag */
        for (i = 0; i < sz; i++)            /* for each element of table */
            if (*s == table[i].source) {    /* is char == table[i].source */
                *t = table[i].code;         /* replace it */
                replaced = 1;               /* set replaced flag */
                break;                      /* get next character */
            }
        if (!replaced)                      /* if not replaced */
            *t = *s;                        /* copy from s to t */
        s++, t++;                           /* increment s and t */
    }
    *t = 0;                                 /* nul-terminate t */
}

Example Use/Output

$ ./bin/encode
Source string : abcdefghijklmnopqrstuvwxyz
Encoded string: dzcbefghijklmnopqrstuvwxya

Always compile with warnings enabled, and do not accept code until it compiles cleanly without warning. To enable warnings add -Wall -Wextra to your gcc compile string. (add -pedantic for several additional warnings). For VS (cl.exe on windoze), add /Wall. For clang, add -Weverything. Read and understand each warning. They will identify any problems, and the exact line on which they occur. You can learn as much about coding by simply listening to what your compiler is telling you as you can from most tutorials.

Look things over and let me know if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • This clearly has helped me a lot. clear my doubts and provide sufficient explanation. I am new to C and i hope one day when ive mastered C language, i will be able to share my knowledge to new programmer as i understand their situation. Thank you so much for your time sir! @david – skylight Sep 27 '17 at 05:14
  • You will. Learning C is a journey, not a race, enjoy the ride. – David C. Rankin Sep 27 '17 at 05:22