-2

I am new to C language and would like to understand the code. The standard input stream is given a string consisting of words with a maximum length of 100 characters. Words consist of Latin characters and are separated by one space. Write to standard output a string containing only palindromes. A palindrome is a word that reads the same in both directions. For example, for input: dad peep aaas. To the exit: dad peep

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

int main(void) {
    int i = 0;
    char word[100];
    int ch, bk, fr;

    while (EOF != (ch = getchar())) {
        if (isspace(ch) != 0) {
            if (i > 0) {
                fr = 0;
                bk = i - 1;
                while (word[fr] == word[bk]) {
                    ++fr;
                    --bk;
                }
                if (fr < bk)//not palindromes
                    i = 0;
                else {
                    while (i > 0)
                        printf("%c", word[--i]);
                    printf("%c", ch);
                }
            }
            if (ch == '\n')
                break;
        }
        else {
            word[i++] = tolower(ch);//check i < sizeof(word)
        }
    }
}

It is not clear to me how the algorithm selects the words we need. I would like to know this step by step due to my extreme inexperience.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
muchas
  • 7
  • You can have a look at this answer (https://stackoverflow.com/questions/4138827/check-string-for-palindrome/4138856#4138856) which explains an algorithm for finding out whether a string is a palindrome or not. The code from your question seems to use the same idea (fr stands for front and bk stands for back I think). As for a step by step explanation of the entire code, that's really beyond the scope of stackoverflow. You might want to start with a C++ programming book. – dcp Feb 01 '22 at 19:33
  • You will find *no* better way of understanding how code works than (1) work out on paper how you *think* it works, then (b) run the code *in a debugger* and validate (or crush) your conclusions from (1). This is a *requirement* for any engineer, as there will not always be (and, in fact, rarely is there) an engineering pool from which you can pull. – WhozCraig Feb 01 '22 at 19:44
  • your debugger is your friend here – pm100 Feb 01 '22 at 19:47
  • One word to add: OMG. – wildplasser Feb 01 '22 at 20:29
  • `if (isspace(ch) != 0) ` is the same as the much simpler `if (isspace(ch)) ` – stark Feb 01 '22 at 20:46

1 Answers1

0

The code is bad and has undefined behavior.

For example let's assume that the input consists from one character 'A' and a space "A ". The word "A" is a palindrome.

But in this while loop

while (word[fr] == word[bk]) {
    ++fr;
    --bk;
}

where initially fr is equal to 0 and bk is equal to 0 due to these assignments (I think fr means front and bk means back)

if (i > 0) {
    fr = 0;
    bk = i - 1;
    //...

there will be access to memory beyond the array word. That is in the first iteration of the while loop the condition evaluates to the logical true.

word[fr] == word[bk]

that is equivalent to

word[0] == word[0]

So the variable bk will be decremented. And in the next iteration of the loop the condition will look like

word[1] == word[-1]
           ^^^^^^^^

My advice: do not search a bad code in the internet and do not spend your time to understand it.

As for you question then within this while loop

while (EOF != (ch = getchar())) {

characters are being written in the character array word starting from the position i equal to 0 until a white space character is encountered.

    if (isspace(ch) != 0) {
        //...
    }
    else {
        word[i++] = tolower(ch);//check i < sizeof(word)
    }

If a white space is encountered

    if (isspace(ch) != 0) {

then the variable i points to the position in the array word after the last written character and the program checks whether the sequence of characters stored in word of the length equal to i is a palindrome.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335