Вопрос

Ok now this isn't imperative for my goal in getting this program to work, but I don't understand why it's storing strange characters into the array in place of the characters typed into the terminal.

Here is what I get when I run the program...

Enter a message: He lived as a devil, eh?

HE  ( ╠ ( ═▓!u ·ñΣ■   jX

Palindrome

Process returned 0 (0x0) execution time : 21.120 s Press any key to continue.


Enter a message: Madam, I am Adam.

MADAM,╠ ( ═▓!u┴:»

Not a palindrome

Process returned 0 (0x0) execution time : 9.039 s Press any key to continue.

As you can see it works ^....

    // Chapter 12 Programming Project #2

    #include <stdio.h>
    #include <ctype.h>
    #include <stdbool.h>

    #define N 50

    bool chk_msg(char message[],char *j);

    int main(void)
    {
        char msg[N], *p;
        int chk = 0;

        printf("Enter a message: ");
        for (p = &msg[0]; p < &msg[N];) {
            *p = toupper(getchar());
            if (((int)*p >= 65) && ((int)*p <= 90)) {
                p++;
            } else if (*p == '\n')
                break;
            printf("%c", msg[chk++]);
        }
        printf("\n");

        if (chk_msg(msg, p))
            printf("Palindrome\n\n");
        else
            printf("Not a palindrome\n\n");

        return 0;
    }

    bool chk_msg(char msg[], char *j)
    {
        char *i;
        bool palindrome = true;

        for (i = &msg[0], j--; i < &msg[N]; i++, j--) {
            if (i == j)
                break;
            else if (*i != *j)
                palindrome = false;
        }

        return palindrome;
    }
Это было полезно?

Решение 2

First, you can use isupper or isalpha to check for upper case or alphabetic characters.

You get strange characters, because you printf("%c", msg[chk++]);. You increase chk, no matter if you inserted a character before.

When you move printf inside the first if, it should work as expected

if (isupper(*p)) {
    p++;
    printf("%c", msg[chk++]);
} else if (*p == '\n')
    break;

A small optimization: You can move the comparison in chk_msg to the for exit condition

for (i = msg, j--; i < j; i++, j--) {
    if (*i != *j)
        palindrome = false;
}

Другие советы

You are validating the input characters with the following condition

if (((int)*p >= 65) && ((int)*p <= 90))

But in this check you are allowing only alphabets (ASCII 65 - 90), but in the input you are inputting also spaces (ASCII 0x20). This is the reason your logic goes wrong and you get garbage in the output.

If you also need spaces in your input change the condition check as follows,

if ((((int)*p >= 65) && ((int)*p <= 90)) || ((int)*p == 20))

Then everything should be fine.

A string in C ends with '\0', the so called terminator. You never add one, so your string just runs off into random memory. Your code gets undefined behavior when dealing with that broken string.

Also, you should never hardcode ASCII values like that, use e.g. isalpha() to filter.

Your message reading function is a big mess:

This works:

for (p = &msg[0]; p < &msg[N];) {
    char c = toupper(getchar());

    if ((c >= 'A') && (c <= 'Z')) {  // filter out anything not between A and Z
        *p++ = c;
        printf("%c", c);
    }
    else if (c == '\n') {
        *p = 0 ;              // put the zero terminator
        break;
    }
}

EDIT:

And your chk_msg is also wrong and overly complicated.

This is a corrected version:

bool chk_msg(char msg[], char *j)
{
    char *i;

    for (i = &msg[0], j--; i < j; i++, j--) {
       if (*i != *j) {
         return true ;
       }
    }

    return false;
}

Thanks again everyone for your input and help

    // Chapter 12 Programming Project #2

    #include <stdio.h>
    #include <ctype.h>
    #include <stdbool.h>

    #define N 50

    bool chk_msg(char message[],char *j);

    int main(void)
    {
        char msg[N] = "", *p;
        int chk = 0;

        printf("Enter a message: ");
        for (p = &msg[0]; p < &msg[N];) {
            *p = toupper(getchar());
            if (isalpha(*p)) {
                p++;
                printf("%c", msg[chk++]);
            } else if (*p == '\n') {
                break;
            }
        }
        printf("\n");
        if (chk_msg(msg, p))
            printf("Palindrome\n\n");
        else
            printf("Not a palindrome\n\n");

        return 0;
    }

    bool chk_msg(char msg[], char *j)
    {
        char *i;

        for (i = &msg[0], j--; i < &msg[N]; i++, j--) {
            if (i == j)
                return true;
            else if (*i != *j)
                return = false;
        }
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top