为什么我一直在字符串末尾添加额外的字符?

时间:2013-06-06 03:09:20

标签: c string

我有字符串,“helLo,wORld!”我希望我的程序将其更改为“Hello,World!”。我的程序工作正常,字符更改正确,但我在感叹号后继续获得额外的字符。我能做错什么?

void normalize_case(char str[], char result[])
{
   if (islower(str[0]) == 1)
   {
      result[0] = toupper(str[0]);
   }

   for (int i = 1; str[i] != '\0'; i++)
   {
      if (isupper(str[i]) == 1)
      {
         result[i] = tolower(str[i]);
      }

      else if (islower(str[i]) == 1)
      {
         result[i] = str[i];
      }

      if (islower(str[i]) == 0 && isupper(str[i]) == 0)
      {
         result[i] = str[i];
      }

      if (str[i] == ' ')
      {
         result[i] = str[i];
      }

      if (str[i - 1] == ' ' && islower(str[i]) == 1)
      {
         result[i] = toupper(str[i]);
      }
   }
}  

4 个答案:

答案 0 :(得分:3)

字符串末尾的额外随机字符通常意味着您忘记了对字符串进行空终止('\0')。你的循环将所有内容复制到结果中,但不包括终止null。

在返回之前在循环之后添加result[i] = '\0';

通常,您将isxxxx()函数(宏)视为返回布尔条件,并且您确保只执行了一个条件链。你会更谨慎地使用else子句来做到这一点。如果代码为空,您的代码实际上会多次复制str[i]。事实上,我认为你可以将你的循环压缩为:

int i;

for (i = 1; str[i] != '\0'; i++)
{
   if (isupper(str[i]))
       result[i] = tolower(str[i]);
   else if (str[i - 1] == ' ' && islower(str[i]))
       result[i] = toupper(str[i]);
   else
       result[i] = str[i];
}
result[i] = '\0';
  

如果我将result[i]放在for循环之外,编译器是否会抱怨i

是的,它会的。在这种情况下,您需要在循环控件外定义i,因为您需要循环后的值。见上面修改的代码。

您可能还会注意到,如果字符串的第一个字符不是小写字母,那么您的预循环代码会悄悄地跳过该字符串的第一个字符,并将垃圾作为结果的第一个字符。你应该写一下:

result[0] = toupper(str[0]);

以便始终设置result[0]

答案 1 :(得分:2)

你不是null终止result所以当你把它打印出来时它会继续运行直到找到null。如果您将i的声明移到for循环之前:

int i ;
for ( i = 1; str[i] != '\0'; i++)

你可以添加:

result[i] = '\0' ;

for循环之后,假设result足够大。

答案 2 :(得分:1)

我冒昧地简化了你的代码,因为你做的很多检查都是不必要的。其他人已经解释了一些要记住的基本要点:

#include <stdio.h> /* for printf */
#include <ctype.h> /* for islower and the like */

void normalise_case(char str[], char result[])
{
    if (islower(str[0]))
    {
        result[0] = toupper(str[0]); /* capitalise at the start */
    }

    int i; /* older C standards (pre C99) won't like it if you don't pre-declare 'i' so I've put it here */

    for (i = 1; str[i] != '\0'; i++)
    {
        result[i] = str[i]; /* I've noticed that you copy the string in each if case, so I've put it here at the top */

        if (isupper(result[i]))
        {
            result[i] = tolower(result[i]);
        }

        if (result[i - 1] == ' ' && islower(result[i])) /* at the start of a word, capitalise! */
        {
            result[i] = toupper(result[i]);
        }

    }

    result[i] = '\0'; /* this has already been explained */
}

int main()
{
    char  in[20] = "tESt tHIs StrinG";

    char out[20] = ""; /* space to store the output */

    normalise_case(in, out);

    printf("%s\n", out); /* Prints 'Test This String' */

    return 0;
}

答案 3 :(得分:1)

你应该在循环结束时添加一个语句result[i] = '\0',因为在C语言中,字符串数组应该以特殊字符'\ 0'结尾,这告诉编译器“这是结束字符串”