ページ 11

学校の課題が分かりません・・・

Posted: 2010年7月14日(水) 07:08
by かむかむ
↓前回のあらすじ・・・

題名の通り、学校の課題でつまってしまいました。
誰か教えてください。 お願いします。


↓問題文
基本: 構造体の配列、関数への構造体の引渡し

基本課題 13..2

name(名前: char型配列), height(身長: float型変数), bloodType(血液型: char型変数)をメンバに持つ構造体を宣言し, 128名分が記憶可能になるようその構造体の配列を定義せよ.また,その配列に対して値を入力し,さらに表示できるようにせよ.構造体のメンバ値を表示するには、ひとつの構造体の各メンバの値を表示する関数を作成すること。

% ./bodyData
1人目のデータ: いい漢 175.5 A
2人目のデータ: 竹達彩菜 169.0 B
3人目のデータ: 能登麻美子 180.4 O
4人目のデータ: 0 0 0 ← 0 0 0 と入力すると終わる.
名前 身長 血液型
いい漢   175.5 A
竹達彩菜 169.0 B
能登麻美子 180.4 O
%


ヒント: 各人の名前、身長、血液型のデータを1行で入力するためには、参考12.1に示されたfgets()関数で、これらを1度に取り込み、最初の空白までを名前とみなし、次の空白までを身長とみなし、次に改行までを血液型をみなせばよい。これらを別々の文字列として、必要に応じて整数や浮動小数点数に変換し、構造体のメンバに設定すること。

ヒント: ひとつの構造体の各メンバの値を表示する関数に構造体を引渡すことを繰り返えせばよい。





↓とりあえず考えて作ってみたもの



#include<stdio.h>
#define BUFFER_SIZE 256
#define NUMBER 128
#define NAME_SIZE 32

struct PROFILE{
char name[NAME_SIZE];

float height;

char bloodType;
}


int main(){
struct PROFILE man[NUMBE[/url];

char buf[BUFFER_SIZE];

int i, j, k, h;
for(i = 0;man.name[0] == '0' && man.height == 0 && man.bloodType == 0;i++){
printf("%d人目のデータ: ", i + 1);

fgets(buf, BUFFER_SIZE, stdin);

for(j = 0;buf[j] != ' ';j++){
man.name[j] = buf[j];
}
for(k = j+1;buf[k] != ' ';k++){
man.height = buf[k];
}
for(h = k+1;buf[h] != '\n';h++){
man.bloodType = buf[h];
}
}
printf("名前\t身長\t血液型\n");
for(j = 0;j <= i;j++){
printf("%s\t%f\t%c\n", man[j].name, man[j].height, man[j].bloodType);
}
return 0;
} 画像

Re:学校の課題が分かりません・・・

Posted: 2010年7月14日(水) 07:14
by かむかむ
そこでstrtokをアドバイスから、使用してみましたが、コンパイルエラーが消えません・・・・
39行目に対し、incompatible types in 代入 っと表示されます

それとchar型変数にAB型というのをきれいに納める方法が分かりません・・

どうすればよいでしょうか?



#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define BUFFER_SIZE 256
#define NUMBER 128
#define NAME_SIZE 32

struct PROFILE{
char name[NAME_SIZE];

float height;

char bloodType;
};

void printProfile(struct PROFILE *pp){
printf("名前:%s\t身長:%f\t血液型:%c\n", pp->name, pp->height, pp->bloodType);

}

int main(){

int i, count;
struct PROFILE man[NUMBE[/url];
char buf[BUFFER_SIZE];

float *height;
char *blood;
count = 0;

height = &man[count].height;
blood = &man[count].bloodType;

while(count < NUMBER){
printf("%d人目: ", count + 1);
fgets(buf, BUFFER_SIZE, stdin);

strcpy(man[count].name, strtok(buf, " "));
height = (float)atof(strtok(NULL, " "));   ←39行目
blood = strtok(NULL, "\n");

count++;

if(man[count].name[0] == '0' && man[count].height == '0' && man[count].bloodType == '0')
break;
}

for(i = 0;i < count;i++){
printProfile(&man);
}

return 0;
}

Re:学校の課題が分かりません・・・

Posted: 2010年7月14日(水) 08:31
by シエル
この課題とまったく同じ課題の質問が前にあったような…
間違いだったらすみません。

Re:学校の課題が分かりません・・・

Posted: 2010年7月14日(水) 08:45
by シエル
すいません。前の質問の続きだったんですね。
私の発言はスルーしてください。。

Re:学校の課題が分かりません・・・

Posted: 2010年7月14日(水) 09:11
by パコネコ
>incompatible types in 代入
互換性のない代入
って書いてました。…知ってました?
私もコピペして起動したところ、ポインタと他の型が混在してますと出てきました。

Re:学校の課題が分かりません・・・

Posted: 2010年7月14日(水) 09:46
by へろりくしょん
atof()関数の戻り値は、double型ですが、キャストされて float型です。 height の型は float*型ですね。
float型から、float*型への代入は出来ません。 ついでにキャストも出来ません。
float型で受けるようにしてください。

とりあえず、
*height = (float)atof(strtok(NULL, " "));
とすることで、コンパイルエラーは消えます。 意図した動きはしないでしょうが。


>strcpy(man[count].name, strtok(buf, " "));
と名前は直接構造体のメンバを指定してるわけですから、
man[count].height = (float)atof(strtok(NULL, " "));
と、身長も直接代入してしまった方が、より直感的でスマートだと思いますよ。


>それとchar型変数にAB型というのをきれいに納める方法が分かりません・・

これはちょっとどうなんでしょうね。

const char *BloodTypeStr[/url] = {"A", "B", "O", "AB"};
man[count].bloodType = 1;
printf("%s", man[count].bloodType);

という風にするか。


かなりトリッキーな方法ですが。
char *hoge = "A";
man[count].bloodType = !hoge[1] ? toupper(*hoge) - 'A' + 10 : 0xAB & 0xFF;
printf("%X\n", (unsigned char)man[count].bloodType);

という風にするか、どちらかしか無いかと。

Re:学校の課題が分かりません・・・

Posted: 2010年7月15日(木) 14:50
by バグ
>>これはちょっとどうなんでしょうね。
>>const char *BloodTypeStr[/url] = {"A", "B", "O", "AB"};
>>man[count].bloodType = 1;
>>printf("%s", man[count].bloodType);
>>という風にするか。

>>かなりトリッキーな方法ですが。
>>char *hoge = "A";
>>man[count].bloodType = !hoge[1] ? toupper(*hoge) - 'A' + 10 : 0xAB & 0xFF;
>>printf("%X\n", (unsigned char)man[count].bloodType);
>>という風にするか、どちらかしか無いかと。


個人的には前者が分かり易いかなぁ?と思いますね(^-^)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE    256
#define NUMBER        128
#define NAME_SIZE    32

struct PROFILE
{
    char name[NAME_SIZE];
    float height;
    char bloodType;
};

int main(void)
{
    char* bloodType[6] = {"0", "A", "B", "O", "AB", "Unknown"};
    char* bld = NULL;
    char buf[BUFFER_SIZE] = {0, };
    int i = 0, j = 0;
    struct PROFILE man[NUMBE[/url];

    do
    {
        /* データの入力 */
        printf("%d人目のデータ: ", i + 1);
        fgets(buf, BUFFER_SIZE, stdin);

        /* 名前の取得 */
        strcpy(man.name, strtok(buf, " "));

        /* 身長の取得 */
        man.height = (float)(atof(strtok(NULL, " ")));

        /* 血液型の取得 */
        bld = strtok(NULL, "\n");
        for (j = 0; j < 6; ++j)
        {
            if (j == 5)
            {
                /* 登録されていない血液型だった */
                man.bloodType = 5;
            }
            else if (strcmp(bld, bloodType[j]) == 0)
            {
                /* 登録されてある血液型と一致した */
                man.bloodType = j;
                break;
            }
        }
    }
    while ((man.name[0] != '0' || man.height != 0.0f || man.bloodType != 0) && ++i < NUMBER);

    /* 入力データの出力 */
    printf("名前\t身長\t血液型\n");
    for(j = 0; j < i; ++j)
    {
        printf("%s\t%.1f\t%s\n", man[j].name, man[j].height, bloodType[man[j].bloodType]);
    }

    return 0;
}