0

私は現在 C を学んでおり、ポインターと構造体の配列について理解するのに少し苦労しています。これが私が書いた簡単なプログラムです:

#include <stdio.h>

typedef struct {                                        /* Define the structure Pokemon that contains a nickname, type and level*/
    char nickname[11];
    char type[11];
    int level;
} Pokemon;

int main(void) {

    char nickname[11];
    char type[11];
    int level;

    for (int i = 0; i < 3; i++) {                      /* Iterate through the loop three times, each time create a new pokemon */
        printf("Pokemon %i \n", i);
        printf("Nickname: ");
        scanf("%s", &nickname);
        printf("Type: ");
        scanf("%s", &type);
        printf("Level: ");
        scanf("%i", &level);

        Pokemon * poke = {nickname, type, level};                /* Insert the pokemon into the array of Pokemon */

        printf("%s, %s, %i", poke->nickname, poke->type, poke->level);
    }
}

基本的には、3 つの特性を持つポケモンの構造体を作成したいと考えています。メイン関数では、ユーザーが 3 匹のポケモンの特性を入力してから、これら 3 つの特性を持つ構造体ポケモンのインスタンスを作成し、これらの特性を stdout に出力する必要があります。このコードを使用すると、コンパイルされますが、警告が表示されます。

pokemon.c:33:9: warning: initialization from incompatible pointer type [enabled by default]
pokemon.c:33:9: warning: (near initialization for ‘poke’) [enabled by default]
pokemon.c:33:9: warning: excess elements in scalar initializer [enabled by default]
pokemon.c:33:9: warning: (near initialization for ‘poke’) [enabled by default]
pokemon.c:33:9: warning: excess elements in scalar initializer [enabled by default]
pokemon.c:33:9: warning: (near initialization for ‘poke’) [enabled by default]

これがなぜなのかはわかりません-私が設定したポインターに関係していると思いますが、私が言うように、まだ頭を悩ませようとしています.

また、ポケモンの各インスタンスを 3 匹のポケモンの配列に入れたいと思います。これまでのところ、私はこれを持っています:

Pokemon p [3];

// This bit inside the for loop and after the 'poke' struct instantiation
p[i] = poke;
printf("%s,%s,%i inserted\n", poke.nickname, poke.type, poke.level );

しかし、それはコンパイルしたくありません-別のポインターエラーだと思います。

4

5 に答える 5

1

必要な機能の説明を考えると、ポインターはまったく必要ないと思います。データを読み取って配列に直接保存するだけです。

int main(void) 
{
    Pokemon p[3];
    for (int i = 0; i < 3; i++) 
    {
        printf("Pokemon %i \n", i);
        printf("Nickname: ");
        scanf("%s", &(p[i].nickname));
        printf("Type: ");
        scanf("%s", &(p[i].type));
        printf("Level: ");
        scanf("%i", &(p[i].level));

        printf("%s, %s, %i", p[i].nickname, p[i].type, p[i].level);
    }
    return 0;
}
于 2013-03-26T09:30:02.720 に答える
1

配列に直接読み込まないのはなぜですか?

#include <stdio.h>
typedef struct {         /* Define the structure Pokemon that contains a nickname, type and level*/
    char nickname[11];
    char type[11];
    int level;
} Pokemon;

int main(void) 
{
    Pokemon p[3];

    for (int i = 0; i < 3; i++)   /* Iterate three times, each time create pokemon */
    {                      
        printf("Pokemon %i \n", i);
        printf("Nickname: ");
        scanf("%10s", p[i].nickname);
        printf("\nType: ");
        scanf("%10s", p[i].type);
        printf("\nLevel: ");
        scanf("%i", &p[i].level);

        printf("\n%s, %s, %i\n", p[i].nickname, p[i].type, p[i].level);
    }
}
于 2013-03-26T09:42:20.407 に答える
1

問題はラインにあります

Pokemon * poke = {nickname, type, level};                /* Insert the pokemon into the array of Pokemon */

したがって、そのように初期化する代わりに、次のように単純に使用することもできます。

    Pokemon *poke = malloc(sizeof(Pokemon));
    strcpy(poke->nickname,nickname);
    strcpy(poke->type,type);
    poke->level=level;   
于 2013-03-26T09:33:09.677 に答える
1
Pokemon p[3];
...
Pokemon poke;
strncpy(poke.nickname, nickname, sizeof(poke.nickname));
strncpy(poke.type, type, sizeof(poke.type));
poke.level = level;
p[i] = poke;

編集:一時的な構造体の初期化を修正しました。

于 2013-03-26T09:16:44.850 に答える
1

この行で:

   Pokemon * poke = {nickname, type, level};

ポインターを宣言しているだけなので、構造体として初期化することはできません。また、構造体には文字配列があるため、文字列ポインターを割り当てることはできません。

C99 を使用している場合は、複合リテラルを使用できます。

   Pokemon * poke = &(Pokemon){.level = level}; 

それ以外の場合は、構造体を宣言してから、代わりにそのアドレスを割り当てる必要があります。

次のセクションでは、

   p[i] = *poke;

指している構造を新しいものにコピーします。

ただし、この方法で初期化しても、文字列は構造体にコピーされません。代わりにできること:

   strcpy(p[i].nickname, nickname);
   strcpy(p[i].type, type);

&次の行の も削除する必要があります。

   scanf("%s", &nickname);
   scanf("%s", &type);
于 2013-03-26T09:19:55.100 に答える