Search code examples
cfile-iopalindromecaesar-cipher

Only certain palindromes get written to file


I am working on a project that requires me to read input from a file called 'input.txt' and to

  1. check if a word is palindrome, if so write it to palindrome.txt
  2. using the Caesar cypher, shift it 13 places and write it to cipher.txt

While the second part seems to be working fine, I got issues with some palindromes not being written to the file, even though the palindrome function does recognize them as palindromes (tested this separately). My input.txt test file contains the following words:

madam quesadilla starman wow cheese racecar

While 'madam' and 'racecar' correctly get written to palindrome.txt, wow does not. Also tried with another palindrome 'beeb' which was also not written to the file. As mentioned, I believe the isPalindrome function works well, while all words of input.txt are also correctly changed for cipher.txt (hence the words do not get skipped completely). Currently lost as to what could be causing this issue. The following is my code:

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

int isPalindrome(char str[])
{
    char t[100];
    int n = strlen(str);
    for(int i=0; i<n; i++)
    {
        t[i] = str[n-i-1];
    }
    if(!strcmp(str, t))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

char* cypher(char str[])
{
    char *encrypted = malloc( sizeof(char) * 100);
    int n = strlen(str);
    for(int i=0; i<n; i++)
    {
        if(str[i] >= 65 && str[i] <= 90)
        {
            encrypted[i] = (str[i]+13-65)%26+65;
        }
        else if(str[i] >= 97 && str[i] <= 122)
        {
            encrypted[i] = (str[i]+13-97)%26+97;
        }
    }
    return encrypted;
}  

int main (void)
{
    FILE *fin, *fpal, *fcip;
    char str[32];
    int ret;
    char *encrypted;

    fin = fopen( "input.txt", "r");
    fpal = fopen( "palindrome.txt", "w");
    fcip = fopen("cipher.txt", "w");

    ret = fscanf( fin, "%s", str );
    while(ret==1)
    {
        if(isPalindrome(str))
        {
            fprintf(fpal, "%s\n", str );
        }
        encrypted = cypher(str);
        fprintf(fcip, "%s\n", encrypted);
        free(encrypted);
        ret = fscanf(fin, "%s", str );
    }

    fclose(fin);
    fclose(fpal);
    fclose(fcip);
    return 0;
}

Solution

  • Your isPalindrome() function is broken — it does not null terminate the string t. I added a simple printf() statement just before your call to isPalindrome() in main():

    printf("word [%s] %d\n", str, isPalindrome(str));
    

    When running the broken version, I got:

    word [madam] 1
    word [quesadilla] 0
    word [starman] 0
    word [wow] 0
    word [cheese] 0
    word [racecar] 0
    word [beeb] 0
    

    After the loop in isPalindrome(), add:

    t[n] = '\0';
    

    Then the output is:

    word [madam] 1
    word [quesadilla] 0
    word [starman] 0
    word [wow] 1
    word [cheese] 0
    word [racecar] 1
    word [beeb] 1
    

    I also got crashes because your code doesn't check that the files are opened successfully. Always check that files are opened successfully.