0

I'm a beginner with C but am trying to make a script which reads input and, ignoring special characters and spaces, outputs the reverse of the input whether or not the letters make a palindrome.

I've tried tweaking the length of the loop in the fix function as I think that's where the issue is but from what I can tell, strlen() is working as expected, the loop is just stopping when it encounters a space.

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

#define MAX 1000 /* The maximum number of characters in a line of  
input 
*/
void fix(char str[], char str2[]);
int main()
{
  char text[MAX], text2[MAX], text3[MAX], text4[MAX], temp;
  int i, j;
  int length;

  puts("Type some text (then ENTER):");

  /* Save typed characters in text[]: */

  fgets(text, MAX, stdin);
  length = strlen(text) - 1;

  strcpy(text2, text);

  i = 0;
  j = length-1;
  while(i < j){
        temp = text[i];
        text[i] = text[j];
        text[j] = temp;
        i++;
        j--;
  }
  /* Analyse contents of text[]: */
  printf("Your input in reverse is:\n");
  printf("%s", text);

  fix(text, text3);
  printf("%s\n", text3);
  fix(text2, text4);
  printf("%s\n", text4);
  if(strcmp(text4, text3) == 0)
        printf("Found a palindrome!\n");
return 0;
}


void fix(char str[], char str2[]){
  int i;
  for(i = 0; i < strlen(str)-1; i+=1){
        if (isalpha(str[i])){
                str2[i] = tolower(str[i]);
        }
  }
}

For an input of "Nurses, run", the reversed string outputs correctly, but there is no output of "Found a palindrome!"

Printing text 3 and 4 prints "nur" and "nurses," respectively.

It seems the loop stops when it encounters a space but I can't figure out why as it should go based on the length of the full input.

Zach Goodman
  • 45
  • 1
  • 7

1 Answers1

1

There is a problem in your fix function that is causing undefined behavior because you only initialize positions in the resulting string that are alpha characters.

Because your requirement is to ignore non-alpha characters, you need an extra counter. Obviously i is going to point at the wrong character if you have to remove characters from your string. So you need to count how many characters you have actually copied into str2.

void fix(char str[], char str2[])
{
    int i, copied = 0;
    for(i= 0; str[i] != '\0'; i++)              // See note 1
    {
        if (isalpha(str[i])) {
            str2[copied++] = tolower(str[i]);   // See note 2
        }
    }
    str2[copied] = '\0';                        // See note 3
}

Notes:

  1. There is no need to call strlen in every test. In fact, you don't need to call it at all -- this just tests for the string's null-terminator.
  2. Notice that copied is incremented here. This guarantees that you won't have gaps if you exclude a character.
  3. You must remember to null-terminate your new string.
paddy
  • 60,864
  • 6
  • 61
  • 103
  • Ok that makes sense, I didn't even realize I would be skipping spaces in the new string when I found a non alphabetical in the first string so thank you. Also, when calling str2[copied++], is copied still equal to 0 when it is first called? Seems like it would be equal to 1 initially – Zach Goodman Feb 13 '19 at 03:14
  • No. Read this: [What is the difference between prefix and postfix operators?](https://stackoverflow.com/q/7031326) – paddy Feb 13 '19 at 03:16
  • Coolness, never heard of this before oddly enough. Thanks! – Zach Goodman Feb 13 '19 at 03:20
  • It is explained early on in most introductory books on C. – paddy Feb 13 '19 at 03:22
  • Gotcha, I’ve just recently had to pick up some c for a class and I’ll be honest, I haven’t done much reading for it haha. Thanks again though! – Zach Goodman Feb 13 '19 at 03:23