为什么它重复源字符串的最后四个字符

why does it repeat the last four characters of the source string

代码应该删除除空格和字母以外的任何字符,并将大写字母转换为小写字母。我的问题是为什么目标字符串会重复源字符串的最后四个字符。

代码

void convertlower(char myString[]) {
  int i = 0, j = 0;
  for (i = 0; i < strlen(myString); i++) {
    if (myString[i] == '[=10=]') {
      myString[j] = '[=10=]';
      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);
}

原文:

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

修改后的文本:

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

你循环的条件是 i < 字符串的 strlen,所以你永远不会看到空终止符,因此不会将它复制到结果中的正确位置。

您可以将条件更改为 <=,我敢打赌它会起作用。

你的第一个 if 永远不会 因为 for 循环中的 i < strlen(myString)

只要把myString[j] = 0;放在函数的底部即可。

但是,在 for 的条件部分使用 strlen 会将 运行 时间从 O(n) 增加到 O(n^2)。

最好只针对 0 (EOS) 测试当前输入字符。

但是,当您省略 !##! 时,您会保留一个额外的 space 字符,因此您需要一些额外的代码。

下面是一些重构代码,显示了函数的四个版本及其输出:

#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] == '[=10=]') {
            myString[j] = '[=10=]';
            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;
}

程序输出如下:

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'