0

「こんにちは、世界!」という文字列があります。プログラムで「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

4 に答える 4

3

'\0'文字列の末尾に余分なランダムっぽい文字がある場合は、通常、文字列を null で終了 ( ) するのを忘れていることを意味します。ループは、終端の null までのすべてを結果にコピーしますが、これは含みません。

result[i] = '\0';戻る前にループの後に追加します。

通常、isxxxx()関数 (マクロ) はブール条件を返すものとして扱い、一連の条件の 1 つだけが実行されるようにします。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]は常に設定されています。

于 2013-06-06T03:11:47.993 に答える
2

あなたはヌル終了していないresultので、それを印刷すると、ヌルが見つかるまで続きます。to の宣言をループのi前に移動すると、次のようになります。for

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

あなたは付け加えられます:

result[i] = '\0' ;

forループの後、これはresult十分な大きさであると仮定しています。

于 2013-06-06T03:12:15.183 に答える
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;
}
于 2013-06-06T03:40:35.427 に答える
1

result[i] = '\0'C 言語では、文字列配列は特殊文字 '\0' で終了する必要があるため、ループの最後にステートメントを追加する必要があります。

于 2013-06-06T05:45:15.357 に答える