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));
答案 0 :(得分: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 a
char *对象,即类型为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”进行下一次输入操作。
(我希望这不是太压倒性的。)
答案 1 :(得分:2)
您正在将未初始化的指针传递给scanf
,它使用它们来执行写操作;这是未定义的行为。您还将字符串指针的地址传递给scanf
和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
答案 2 :(得分:0)
您已为包含三个指针的结构分配了空间。您还需要为两个字符串分配空间。您还应确保next
字段已正确初始化 - 可能为NULL。
就个人而言,我不打扰DATAS
typedef,最好保留宏的所有大写名称(尽管FILE *
类型)。