Bhavya Bhavya - 2 months ago 22
C Question

Issue with String position appending C program

I am trying to write program for piglatin. I was not getting the output what I am expecting.

take the first letter of a “word” and appending that letter to the end of the word with “ay” added to the end as well.

Input : Darrin, what are you doing with 500 and 100?

Output: arrin, hatway reaay ouyay oingday ithway 500 ndaay 100?

Expected Output: arrinday,hatway reay ouyay oingday ithway 500 nday 100?

What's wrong with output : First word not appended with ay

Since I am appending 'ay', I need eliminate the extra 'a' if the word starts with a or end's with 'a'. I just need add ay at the end instead of first letter + ay. For example: Input is Alex and allen are 500 Output should be lexay nday llenay

Also if the starting letter is not alphabet then we should print the same word.

Please help me to solve this

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

static char inputBuffer[100];
static char outputBuffer[100];


void translate (void)
{
char bufferValue;
char firstLetter;
int j = 0, k = 0, m = 0;

printf("\n");

while (j < (sizeof(inputBuffer) - 1))
{
bufferValue = inputBuffer[j];

if (((bufferValue >= 'A') && (bufferValue <= 'Z')) || ((bufferValue >= 'a') && (bufferValue <= 'z')))
{
if (j == 0)
{
firstLetter = bufferValue;

}
else if (inputBuffer[j-1] == ' ')
{
firstLetter = bufferValue;
}
else
{
printf("%c", bufferValue);
outputBuffer[m] = bufferValue; m++;
}
}
else if ((bufferValue == ' ') && !(
((inputBuffer[j-1] < 'A') ||
((inputBuffer[j-1] > 'Z') && (inputBuffer[j-1] < 'a')) ||
(inputBuffer[j-1] > 'z'))))
{
printf("%cay%c", firstLetter, bufferValue);
outputBuffer[m] = firstLetter; m++;
outputBuffer[m] = 'a'; m++;
outputBuffer[m] = 'y'; m++;
outputBuffer[m] = bufferValue; m++;
firstLetter = ' ';
}
else
{
printf("%c", bufferValue);
outputBuffer[m] = bufferValue; m++;
}
j++;

}

printf("\n final output: %s",outputBuffer);

return;
}

int main(void)
{
printf("enter the string\t");
fflush(stdin);
gets(inputBuffer);

printf ("\nInput buffer contents: %s", inputBuffer);
translate();
return 0;
}

Answer

The real problem is that you didn't see the forest through the trees which made the implementation awful to read. To add insult to injury, you decided to break the basic rules of code locality (not using globals unless necessary) and DRY (functions to tell if a charater is a letter exist in the standard library of any language I can think of, don't reimplement it), which made it pretty much irrecoverable as far as maintenance is concerned.

Now, let's read the task description again:

take the first letter of a “word” and appending that letter to the end of the word with “ay” added to the end as well.

Notice what already stands out because of quoting: word.

So, I'd divide the implementation into two distinct tasks:

  1. Iterate through a sentence word by word.
  2. Once you can reliably identify words, do the piglatin thing.

The end result of might look like this:

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

void piglatinize(const char* in)
{
    static const char* SEP = " .,?";  // word separators

    // Iterate input by words
    const char *sep = NULL, *word = NULL, *end = in;
    while (sep = end,  // separators from previous word end
           word = &end[strspn(end, SEP)],  // start of word
           end = &word[strcspn(word, SEP)],  // end of word
           *sep)  // iterate until we hit terminating zero character
    {
        int wordlen = (int)(end - word);
        int seplen = (int)(word - sep);
        if (wordlen > 0 && isalpha(word[0]))  // word starts with a letter, pig it!
        {
            char firstletter = tolower(word[0]);
            const char* suffix = (firstletter == 'a') ? "y" : "ay";
            printf("%.*s%.*s%c%s",
                seplen, sep,            // separators from previous word
                wordlen - 1, &word[1],  // word without first letter
                firstletter, suffix);
        }
        else  // not a real word, just print unchanged
        {
            printf("%.*s%.*s", seplen, sep, wordlen, word);
        }
    }
}

int main()
{
    piglatinize("Darrin, what are you doing with 500 and 100?");
}

I admit the while loop continuation condition is a handful. If you have trouble understanding this example you might want to read on strspn (and its opposite strcspn) and the comma operator.