1
  typedef struct Data* DATAS;

  struct Data {
      char *name;
      char *city;
      DATAS next;
  };
  typedef struct Data DATA;

  int main(void){
     DATAS tmp;

     tmp=(DATAS) malloc(sizeof(DATA));   
     printf("please enter name:\n");
     scanf("%s",&tmp->name);
     printf("%s\n",&tmp->name);
     printf("please enter city:\n");
     scanf("%s",&tmp->city);
     printf("%s\n",&tmp->name);
     printf("%s\n",&tmp->city);

  return 0;
  }

これは宿題の一部です。というかコンセプトです。「typedef struct Data* DATAS;」を使用する必要があります。それは私を捨てています。これを実行すると、名前が都市の一部で上書きされるため、結果としてこれが得られます。

please enter name:
name
name
please enter city:
city
namecity
city

どんな助けでも素晴らしいでしょう。ありがとう。を使用してmallocのさまざまなバリアントを試しました

tmp=(DATAS) malloc(sizeof(DATA));
tmp=(DATA) malloc(sizeof(DATA));
4

3 に答える 3

4

を割り当てる最良の方法struct Dataは次のとおりです。

struct Data *tmp;
tmp = malloc(sizeof *tmp);
if (tmp == NULL) {
    /* malloc failed, abort or take corrective action */
}

ポインタ型のtypedefを定義することはお勧めしません(少なくとも私は)。明示的に使用struct Data *すると、ポインタを扱っていることが読者に明確になります。

構造体型のtypedefを定義することも不要です。typedefは、既存の型の新しい名前を宣言するだけです。あなたのタイプはすでに完全に良い名前を持っています、struct Data。確かに、structキーワードを繰り返し入力する必要がありますが、それは実際には問題ではありません。

の結果をキャストするmalloc必要はありません。malloc結果を返しますvoid*。これは、暗黙的にポインタ型に変換できます。キャストは、必要なを忘れるなどのエラーを隠すことができ#include <stdlib.h>ます。

しかし、これらはスタイルの問題です。現在のコード:

tmp=(DATAS) malloc(sizeof(DATA));

大丈夫です、そしてそれはうまくいくはずです。問題はコードの後半にあります。

scanf"%s"フォーマットを使用すると、 char* argument. You're giving it the *address* of achar *オブジェクト、つまり型の値が必要になりますchar**。コンパイラは必ずしもこれについて警告するわけではありません。したがって、この:

scanf("%s",&tmp->name);

する必要があります:

scanf("%s", tmp->name);

しかし、それはまだ問題です。なぜなら、tmp->nameは初期化されていないポインタだからです。おそらくメモリ内のランダムな場所を指しており、呼び出しはその場所にデータを保存しようとします。または、無効なアドレスを保持している可能性があり、クラッシュを引き起こします。動作は未定義です。

名前を保持するためのスペースを割り当て、tmp->nameそれを指すようにする必要があります。malloc()ここで別の呼び出しが必要になる可能性があります。

では、どのくらいのスペースを割り当てる必要がありますか?scanf("%s", ...)読み取るバイト数に制限がないため、これに対する適切な答えはありません。割り当てられたスペースがいくら大きくても、十分なデータを入力するとオーバーフローする可能性があります。

おそらくまだそれについて心配する必要はありません。将来のためにそれを覚えておいてください。今のところ、「十分な」スペース(たとえば、100バイト)を割り当てることができ、データを入力しすぎないように注意してください。プログラムを機能させるには、これで十分です。(のドキュメントを確認し、のscanfようなものの使用を検討してください"100s"。)

scanf("%s", ...")また、空白で区切られた入力文字列を読み取ることに注意してください。「JohnDoe」と入力すると、「John」のみが読み取られ、次の入力操作のために「Doe」が残ります。

(これがあまりにも圧倒的ではないことを願っています。)

于 2012-08-05T02:12:43.220 に答える