我正在编写一个程序,必须使用用户输入来为结构的某些部分赋值。我需要创建一个指向结构的指针,我将通过它作为一个唯一的参数,用于单独打印结构的每个部分的函数。我还必须为结构使用malloc内存。就像现在一样,程序编译并运行main并询问用户输入。在收集最后一个用户输入之后以及当我假设运行对printContents函数的调用时,会发生分段错误。任何帮助将不胜感激!
#include <stdio.h>
#include <stdlib.h>
struct info
{
char name[100], type;
int size;
long int stamp;
};
void printContents(struct info *iptr);
int main(void)
{
struct info *ptr=malloc(sizeof(struct info));
printf("Enter the type: \n");
scanf("%c", &(*ptr).type);
printf("Enter the filename: \n");
scanf("%s", (*ptr).name);
printf("Enter the access time: \n");
scanf("%d", &(*ptr).stamp);
printf("Enter the size: \n");
scanf("%d", &(*ptr).size);
printf("%c", (*ptr).type);
printContents(ptr);
}
void printContents(struct info *iptr)
{
printf("Filename %s Size %d Type[%s] Accessed @ %d \n", (*iptr).name, (*iptr).size, (*iptr).type, (*iptr).stamp);
}
答案 0 :(得分:0)
ptr-&gt;成员就像访问结构变量吧? scanf()usr&amp; ptr-&gt;成员也可以获得相同的值。对于char输入,仅使用ptr-> charmember。
答案 1 :(得分:0)
检查运营商优先顺序。这是&(*ptr).type
你要做的事情吗?也许&((*ptr).type)
?
答案 2 :(得分:0)
首先让我们这么做。我们假设代码已经编写,编译器告诉我们什么没用,我们没有调试器。首先我们输入一些诊断输出语句,我们发现崩溃发生在printContents
:
printf("testing four\n"); /* we see this, so the program gets this far */
printf("Filename %s Size %d Type[%s] Accessed @ %d \n", (*iptr).name, (*iptr).size, (*iptr).type, (*iptr).stamp);
printf("testing five\n"); /* the program crashes before this */
如果我们仍然看不到错误,我们通过准备minimal compete example来缩小问题范围。 (这是一项非常有价值的技能。)我们一遍又一遍地编译和运行代码,对事情进行评论。当我们发表评论并且代码仍然是段错误时,我们会完全删除它;但如果将其评论出来会导致问题消失,我们将其重新放入。最终我们得到了一个最小的案例:
#include <stdio.h>
int main(void)
{
char type;
type = 'a';
printf("Type[%s]\n", type);
}
现在应该很明显:当我们printf("%s", x)
某事时,printf
期望x
成为字符串。也就是说,x
应该是指向以空字符结尾的字符数组的第一个元素(即地址)的指针。相反,我们给它一个字符(在这种情况下为'a'),它将其解释为数字(在本例中为97),并尝试在内存中转到该地址并开始读取; 我们很幸运没有比segfault更糟糕的事情。修复很容易:决定type
应该是char
还是char[]
,如果它是{ {1}}然后将char
语句更改为“%c”,如果它是printf
,则更改其声明。
现在这是一个简单的方法。如果我们使用像gcc这样的好编译器,它会警告我们我们正在做一些可疑的事情:
char[]
将来,您可以通过某种方式为自己省去所有这些麻烦。得到一个神秘的错误和回溯,而不是编写大量的代码,你可以以较小的增量编写。如果您一次在gcc foo.c -o foo
foo.c:35: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘int’
语句中添加了一个术语,那么您可能会看到错误何时出现以及哪个术语应该归咎于此。
请记住:从小而简单开始,一次添加一点复杂性,在每一步测试,永远不会添加到不起作用的代码。