2
votes

The code is supposed to remove any character except spaces and letters and convert the uppercase letters to lowercase letters. My question is why does the target string repeat the last four characters of the source string.

CODE

void convertlower(char myString[]) {
  int i = 0, j = 0;
  for (i = 0; i < strlen(myString); i++) {
    if (myString[i] == '\0') {
      myString[j] = '\0';
      break;
    }

    if ((myString[i] >= 'A' && myString[i] <= 'Z') ||
        (myString[i] >= 'a' && myString[i] <= 'z') ||
        (myString[i] == ' ')) {
      if (myString[i] >= 'A' && myString[i] <= 'Z') {
        myString[j] = myString[i] + 32;
        j++;
      } else {
        myString[j] = myString[i];
        j++;
      }
    }
  }
}

int main() {
  char myString[] =
      "The quick Brown Fox jumps over the Lazy Dog and the !##! LAZY DOG is "
      "still sleeping";
  printf("Original Text:\n%s\n", myString);
  convertlower(myString);
  printf("Modified Text:\n%s\n", myString);
}

Original Text:

The quick Brown Fox jumps over the Lazy Dog and the !##! LAZY DOG is still sleeping

Modified Text:

the quick brown fox jumps over the lazy dog and the lazy dog is still sleepingping

2

2 Answers

2
votes

You’re looping on the condition that i is < strlen of the string, so you never see the null terminator and thus don’t copy it to the right place in the result.

You could change the condition to <= and it would work I bet.

1
votes

Your first if will never be true because of the i < strlen(myString) in your for loop.

Just put myString[j] = 0; at the bottom of the function.

But, using strlen in the conditional part of the for increases the running time from O(n) to O(n^2).

Better to just test the current input char against 0 (EOS).

But, when you elide !##! you keep an extra space char, so you'll need some extra code for that.

Here's some refactored code showing four versions of the function and their output:

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

#define DOFNC(_fnc) \
    dofnc(str,_fnc,#_fnc)

void
convertlower(char myString[])
{
    int i = 0,
        j = 0;

    for (i = 0; i < strlen(myString); i++) {
        if (myString[i] == '\0') {
            myString[j] = '\0';
            break;
        }

        if ((myString[i] >= 'A' && myString[i] <= 'Z') ||
            (myString[i] >= 'a' && myString[i] <= 'z') ||
            (myString[i] == ' ')) {

            if (myString[i] >= 'A' && myString[i] <= 'Z') {
                myString[j] = myString[i] + 32;
                j++;
            }
            else {
                myString[j] = myString[i];
                j++;
            }
        }
    }
}

void
convert2(char myString[])
{
    int i = 0,
        j = 0;

    for (i = 0; i < strlen(myString); i++) {
        if ((myString[i] >= 'A' && myString[i] <= 'Z') ||
            (myString[i] >= 'a' && myString[i] <= 'z') ||
            (myString[i] == ' ')) {

            if (myString[i] >= 'A' && myString[i] <= 'Z') {
                myString[j] = myString[i] + 32;
                j++;
            }
            else {
                myString[j] = myString[i];
                j++;
            }
        }
    }

    myString[j] = 0;
}

void
convert3(char myString[])
{
    const char *src = myString;
    char *dst = myString;

    for (int chr = *src++;  chr != 0;  chr = *src++) {
        if (chr >= 'A' && chr <= 'Z') {
            *dst++ = chr + 32;
            continue;
        }

        if ((chr >= 'a' && chr <= 'z') || (chr == ' ')) {
            *dst++ = chr;
            continue;
        }
    }

    *dst = 0;
}

void
convert4(char myString[])
{
    const char *src = myString;
    char *dst = myString;
    int last = -1;

    for (int chr = *src++;  chr != 0;  chr = *src++) {
        if (chr >= 'A' && chr <= 'Z') {
            last = chr + 32;
            *dst++ = last;
            continue;
        }

        if (chr >= 'a' && chr <= 'z') {
            last = chr;
            *dst++ = chr;
            continue;
        }

        if (chr == ' ') {
            if (last == chr)
                continue;
            last = chr;
            *dst++ = chr;
            continue;
        }
    }

    *dst = 0;
}

void
dofnc(const char *str,void (*fnc)(char myString[]),const char *who)
{
    char *obuf = malloc(strlen(str) + 10);

    strcpy(obuf,str);
    fnc(obuf);

    printf("\n");
    printf("dofnc: %s\n",who);
    printf("'%s'\n",obuf);

    free(obuf);
}

void
dotst(const char *str)
{

    printf("dotst:\n");
    printf("'%s'\n",str);
    DOFNC(convertlower);
    DOFNC(convert2);
    DOFNC(convert3);
    DOFNC(convert4);
}

int
main(void)
{

    //dotst("The quick Brown Fox jumps over the Lazy Dog and the !##! LAZY DOG is still sleeping");
    dotst("The Brown Fox jumps over the Lazy Dog and the !##! LAZY DOG is still sleeping");

    return 0;
}

Here's the program output:

dotst:
'The Brown Fox jumps over the Lazy Dog and the !##! LAZY DOG is still sleeping'

dofnc: convertlower
'the brown fox jumps over the lazy dog and the  lazy dog is still sleepingping'

dofnc: convert2
'the brown fox jumps over the lazy dog and the  lazy dog is still sleeping'

dofnc: convert3
'the brown fox jumps over the lazy dog and the  lazy dog is still sleeping'

dofnc: convert4
'the brown fox jumps over the lazy dog and the lazy dog is still sleeping'