1

ご清聴ありがとうございました...本当に混乱しています..charに配列を指定したときにchar型を大文字に変換できないのはなぜですか...この「chardrh[1]」のように?

これが私のコードです..このコードはまだ完成していません..途中で立ち往生しています。

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <ctype.h>

using namespace std;
int main()
{
    char nama[50], gender[6], drh[1];
    int tahun_l, usia;
    float berat, tinggi, berat_i;

    printf("Masukkan Data Anda\n\n");
    // INPUT ZONE

    //First
    printf("Nama\t\t\t\t: ");
    scanf("%[^\n]", &nama);

    printf("Tahun Lahir (yyyy)\t\t: ");
    scanf("%d", &tahun_l);

    printf("Gol Darah (A/B/C)\t\t: ");
    scanf("%s", &drh);

    system("cls");

    //Second
    printf("Masukkan Data Anda\n\n");

    printf("Nama\t\t\t\t: %s\n", nama);
    fflush(stdin);

    printf("Tahun Lahir (yyyy)\t\t: %d\n", tahun_l);
    fflush(stdin);

    printf("Gol Darah (A/B/O)\t\t: %s\n", drh);
    drh = toupper(drh); //not working
    fflush(stdin);

    printf("Jenis Kelamin (Pria/Wanita)\t: ");
    scanf("%s", &gender);

    printf("Berat Badan (kg)\t\t: ");
    scanf("%f", &berat);

    printf("Tinggi Badan (cm)\t\t: ");
    scanf("%f", &tinggi);

    //FORMULA ZONE
    usia    = 2008 - tahun_l;
    berat_i = tinggi - 100 - (0.1 * (tinggi - 100));
    //OUTPUT ZONE
    printf("\n%s, berdasarkan data yang Anda masukkan,\n", nama);
    printf("Anda berjenis kelamin %s, saat ini Anda berusia %d tahun,\n", gender, usia);
    printf("Berat badan = %.2f kg, tinggi badan = %.2f cm, golongan darah = %s \n", berat, tinggi, drh);
    printf("\nBerat badan ideal adalah %.2f", berat_i);

    getche();
    return 0; 
}
4

3 に答える 3

3

このtoupper関数は、文字列ではなく、単一の文字で機能します。文字列全体を大文字に変換する必要がある場合は、ループを使用する必要があります。

for (char *p = drh ; *p ; *p = toupper(*p), p++)
    ;

ただし、drhバッファには十分な長さがありません。ヌルターミネータに合わせるには、2文字が必要です。

char nama[50], gender[6], drh[2];
//  Add 1 char for terminator ^---- HERE

また、それdrhが1文字であることがわかっているので、

*drh = toupper(*drh);
于 2012-09-30T03:05:39.013 に答える
2

関数toupperは1文字を取り、それに文字の配列を渡します(はい、drh[1]1文字の配列です)。このコード行は、配列では機能しません。

drh = toupper(drh);

そのような配列をコピーすることはできないからです。charあなたはおそらくシングルとを混同していchar[1]ます。オプションは1つだけで、それはの宣言をに変更することdrhですchar drh;

そして、次のコード行を変更する必要があります。

scanf("%s", &drh);

に:

scanf("%c", &drh);

文字列ではなく文字を読んでいるからです。

于 2012-09-30T03:04:26.830 に答える
0

toupper個々の文字で機能しますが、配列全体に適用しようとしています。コンパイラは、整数をポインタに変換したり、そのようなものに変換したりすることについて不平を言うはずです。そうでない場合は、今すぐ停止して警告をオンにしてください。

Cで「文字列」(ヌル文字で終わる文字配列)全体を大文字にするには、次のように自分で文字をループする必要があります。

for (char *p = drh; *p; p++)
  *p = toupper(*p);

これはこれを行うための最も慣用的な方法ですが、何が起こっているのかをより明確にする可能性のある別の方法も書きましょう。

char *p = drh;
while (*p != '\0')     // until we reach the end of the string
{
    *p = toupper(*p);  // upcase the character currently pointed to by 'p'
    p++;               // advance to the next character
}

編集: 1文字の配列をに渡していることに気づきませんでしたscanf。これにより、必然的にスタックが破損します。ユーザーが協力して1文字しか入力しなくても、配列に2文字(ユーザーが入力した文字と必須のNULターミネーター)scanfが書き込まれるためです。1文字を読み取るために使用する場合は、これを作成する必要があります。そして、それでも、ユーザーが複数の文字を入力した場合(そうでない場合)は役に立ちません。このプログラムを書く適切な方法は、(または、より良いのは)行全体を読み取ってから、手で(つまり、ではなく)それらをつぶすために使用することです。基本的に長期的には聞いたことを忘れたいchar drh[2]scanf("%s")fgetsgetlinesscanfscanfまたはその親戚。ただし、一度に1つの問題を解決したいと思ったことを非難するつもりはありません。

于 2012-09-30T03:05:04.513 に答える