我输了,输出不正确(C)

时间:2013-10-22 03:28:54

标签: c

所以我为我的班级做了一个作业,并且应该有一个结构,两个函数和一个主函数。结构需要有3个变量,函数需要有这些名称,而main只能有3行。这是我的第一个C程序,我们整年都在做c ++,所以我有点失落。我编写了程序并编译,但在输入值后,输出等于一个基本上随机的值。

//Joshua    
#include <stdio.h>

struct Person
{
    char name[100];
    int age;
    float gpa;
};

void fill_person(struct Person* per)
{
    char name[100];
    printf("Enter a name.\n");
    fgets(name, 100, stdin);
    per->name = name;

    int age;
    printf("Enter an age. \n");
    scanf("%d", &age);
    per->age = age;

    float gpa;
    printf("Enter a GPA. \n");
    scanf("%f", &gpa);
    per->gpa = gpa;

}

void show_person(struct Person* per)
{
    char name[100];
    printf("The person's name is %c\n", &name);

    int age;
    printf("Their age is %d\n", &age);

    int gpa;
    printf("Their GPA is %f", &gpa);
}

int main()
{
    struct Person per;
    fill_person(&per);
    show_person(&per);
}

6 个答案:

答案 0 :(得分:1)

检查printf中的show_person语句 - 在每个字符串后传递错误类型的变量时,它们传递的值与struct无关你传了进来。

fgets周围的内容也无法按照您的预期运作。例如。 char string1[100], string2[100]; string2 = string1;不会将string1的内容复制到字符串2。

答案 1 :(得分:1)

因为您没有使用'per'变量,所以您传递了show_person函数。您基本上是在该函数中创建新变量,然后显示它们。你需要使用per-&gt;并删除函数中变量的声明。

答案 2 :(得分:1)

您正在打印的name和其他变量是未初始化的局部变量。您想要从Person对象中打印名称。

答案 3 :(得分:1)

这样更好,你不需要使用那些局部变量,你可以直接读到你的struct:

void fill_person(struct Person* per)
{
  printf("Enter a name.\n");
  fgets(per->name, 100, stdin);

  printf("Enter an age. \n");
  scanf("%d" ,&per->age);

  printf("Enter a GPA. \n");
  scanf("%f",&per->gpa);
}

检查Tommy对你的其他功能问题的回答。

答案 4 :(得分:1)

tl; dr“输出等于一个基本上随机的值”因为

  1. printf使用不当;和
  2. per->name = name不正确。
  3. 固定打印

    使用&someVariable / scanf / etc时fgets有意义,因为这些函数必须修改变量(在C中这是通过传递指针来完成的)变量);但是,在使用printf时,一个不应传递指向变量的指针:只传递值!

    此外,使用已读取的数据(此处可通过提供的per参数获得)。使用新的本地未分配变量(即使没有&someVariable)将导致不可预测的输出。

    void show_person(struct Person* per)
    {
        // Also note use of %s, not %c - refer to the printf documentation.
        printf("The person's name is %s\n", per->name);
        printf("Their age is %d\n", per->age);
        // ..
    

    修正阅读

    现在,fill_person还有一个至关重要的缺陷(它甚至可以编译吗?)。这是因为我不会用C x = y“复制”C中的字符串,因为它只分配一个值,可能是一个字符指针。将strcpy或更好的fgets直接用于per->name字符数组。

    void fill_person(struct Person* per)
    {
        printf("Enter a name.\n");
        fgets(per->name, 100, stdin);
        // While the following intermediate variables could also be eliminated
        // using them won't affect the semantics of the code.
        // ..
    

    我希望上面的示例存根和笔记让你顺利上路!

答案 5 :(得分:0)

因为C中的结构在C ++ / java中没有像“protected”或“private”那样归属,而在c ++中没有这样的指针*,所以你可以在函数中改变struct中member的值。我认为你应该像下面的代码一样编写show_person函数:

void show_person(struct Person* per)
{
printf("The person's name is %c\n",per.name );

int age;
printf("Their age is %d\n",per.age);

int gpa;
printf("Their GPA is %f", per.gpa);
}

使用&amp;变量时,它表示内存中变量的地址,而不是其值。你应该像那样编写你的功能

printf("The person's name is %c\n",name );