0

Cのtoupper()関数がどのように機能するのか疑問に思っています。私は以下のコードでそれを試していますが、私は間違いなく何か間違ったことをしています。コードはコンパイルされますが、toupper()に渡された引数は大文字になりません...

char **copyArgs(int argc, char **argv) {
    char **a = malloc(sizeof(char *) * (argc));

    int i;
    for(i = 0; i < argc; i++) {
        int size = strlen(argv[i]);
        a[i] = malloc(sizeof(char) * (size + 1));
        strcpy(a[i], argv[i]);
        a[i] = toupper(a[i]);
    }
    return a;
}

これを「onetwo」でテストすると、「ONE TWO」ではなく、「onetwo」になります。アドバイスをいただければ幸いです。

4

1 に答える 1

5

toupper単一の文字を大文字に変換します。あなたの場合、char暗黙的な変換での C の許しに感謝する代わりに、ポインターを渡しているため、正しく機能しないことは明らかです。おそらく、「キャストなしの整数変換への暗黙的なポインター」という警告が表示されます。これは、何か非常に間違ったことをしているという強い兆候です。

プラットフォームintがポインターと同じくらい大きい (または、少なくとも、使用しているポインターに対して十分大きい) という理由だけで、すべてが爆発するわけではありません。toupperそれを文字として解釈しようとしint、それがアルファベットではないことを発見し、それを変更せずに返します。int他のプラットフォームでは、変換へのポインターの切り捨てと、範囲toupper外の整数unsigned char(プラスEOF) の動作が未定義であるため、おそらくプログラムがクラッシュします。

文字列全体を大文字に変換するには、すべての文字を繰り返し処理し、toupperそれぞれを呼び出す必要があります。これを行う関数を簡単に書くことができます:

void strtoupper(char *str)
{
    while(toupper((unsigned char)*str++))
        ;
}

unsigned char文字の分類と変換を扱うキャストオール C 関数には、 (そのままにしておく) または an の値である が必要であることに注意してください。その理由は悲しくて複雑で、すでに別の回答で詳しく説明しています。intEOFunsigned char

toupper それでも、設計上、マルチバイト文字エンコーディング (UTF-8 など) では確実に動作しないことに注意してください。そのため、現代のテキスト処理では実際の場所がありません (一般に、(ひどく) 設計されたほとんどの C ロケール機能と同様)。別の時代に)。

于 2013-02-24T23:24:42.343 に答える