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

分配 a 的最佳方法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* 对象,即 type 的值char**。编译器不一定会就此发出警告。所以这:

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

应该:

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

但这仍然是一个问题,因为tmp->name它是一个未初始化的指针。它可能指向内存中的某个随机位置,并且调用尝试在该位置存储数据。或者它可能持有无效地址,从而导致崩溃。行为未定义。

您需要分配空间来保存名称,并导致tmp->name指向它。您可能需要malloc()在这里再打一个电话。

那么你需要分配多少空间呢?好吧,对此没有好的答案,因为scanf("%s", ...)它没有限制它将读取多少字节。不管分配的空间有多大,如果输入足够的数据,就会溢出。

您可能还不需要担心这一点。只是为了将来记住它。现在,您可以分配“足够”的空间(例如 100 个字节)并注意不要输入太多数据。这应该足以让您的程序正常工作。(检查文档scanf,并考虑使用类似的东西"100s"。)

请记住,scanf("%s", ...")读取以空格分隔的输入字符串;如果你输入“John Doe”,它只会读取“John”,留下“Doe”用于下一个输入操作。

(我希望这不会太过分。)

于 2012-08-05T02:12:43.220 回答
2

您将未初始化的指针传递给scanf,它使用它们来执行写入;这是未定义的行为。您还将字符串指针的地址传递给scanfand printf; C 中的字符串已经是指针,您不应该将指向它们的指针传递给 I/O 例程。

如果您知道名称/城市名称中的字符数限制,则可以读取如下字符串:

char buf[128]; // 127 is the limit; buffer needs an extra character
printf("please enter name:\n");
scanf("%127s", buf);
size_t len = strlen(buf)+1; // plus one for null terminator
tmp->name = malloc(len);
strcpy(tmp->name, buf);
printf("%s\n", tmp->name); // No ampersand
于 2012-08-05T01:57:46.527 回答
0

您已经为包含三个指针的结构分配了空间。您还需要为这两个字符串分配空间。您还应该确保该next字段已正确初始化——可能使用 NULL。

就个人而言,我不会打扰DATAStypedef,最好保留宏的所有大写名称(FILE *尽管类型)。

于 2012-08-05T02:02:55.240 回答