简体   繁体   English

无法从 C 中的结构打印数据

[英]Can't print data from struct in C

My goal here is to print student data contain in struct我的目标是打印struct中包含的学生数据

My question is why i unable to print out data from struct?我的问题是为什么我无法从结构中打印出数据?

Here is my code:这是我的代码:

typedef struct _STUDENT{
    char *fullname;
    int ID;
    float scores[6];
} STUDENT;
void input(STUDENT* student){
    fflush(stdin);
    printf("\nInput Student Fullname: ");
    scanf("%s", &student->fullname);
    printf("\nInput ID: ");
    scanf("%s",&student->ID);
    for(int i = 0; i < 6; i++){
        printf("\nInput point for course %d: ", i+1);
        scanf("%f",&student[i].scores);
    }
    
}
void output(STUDENT* student){
    
    printf("\nStudent Fullname: %s", student->fullname);
    printf("\nStudent ID: %d", student->ID);
    for(int i = 0; i < 6; i++){
        printf("\nStudent Score: %f", student[i].scores);   
    }
    
}

int main(){
    
    STUDENT* students;
    int size;
    printf("Enter number of student: ");
    scanf("%d",&size);
    
    students = (STUDENT*)calloc(size,sizeof(STUDENT));
    
    for(int i =0;i<size;i++){

        input(students+i);
    }

    
    for(int i =0;i<size;i++){
        output(students+i);
    }
    return 0;
}

here is the output:这是 output:

Student Fullname:?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
Student ID: 50
Student Score: 0.000000
Student Score: 0.000000
Student Score: 0.000000
Student Score: 0.000000
Student Score: 0.000000
Student Score: 0.000000

under the output funtion i try to print out some data but none of it been print在 output 功能下,我尝试打印出一些数据,但没有一个被打印

My question is why i unable to print out data from struct?我的问题是为什么我无法从结构中打印出数据?

In part, the student data are just not what you expect, on account of numerous errors in your input() function.在某种程度上,由于您的input() function 中有许多错误,学生数据并不是您所期望的。 You could have discovered this for yourself by running the program under control of a debugger, and your compiler might have warned you about several of the errors, at least if you turned up the warning level.您可以通过在调试器的控制下运行程序来自己发现这一点,并且您的编译器可能会警告您一些错误,至少在您提高警告级别时是这样。 Always pay attention to compiler warnings.始终注意编译器警告。

Issues with your input() function include:您的input() function 的问题包括:

  • Do not fflush() the standard input.不要fflush()标准输入。 Flushing is about output , not input.冲洗大约是output ,不是输入。 If fflush(stdin) happens to produce an effect that you find desirable then that is not portable.如果fflush(stdin)碰巧产生了您认为理想的效果,那么它是不可移植的。 If you want to ignore some input then read and discard it.如果您想忽略某些输入,请阅读并丢弃它。

    As long as you are using scanf or fscanf for input, however, be aware that most field directives skip leading whitespace, including newlines.但是,只要您使用scanffscanf进行输入,请注意大多数字段指令会跳过前导空格,包括换行符。 In that case, however, be aware also that these functions are difficult to use correctly.但是,在这种情况下,还要注意这些功能很难正确使用。 You may be better served by fgets() combined with sscanf() , though that's not a cure-all. fgets()结合sscanf()可能会更好地为您服务,尽管这不是万能的。

  • You do not check the return values of your scanf() calls.您不检查scanf()调用的返回值。 This is not in itself an error per se , but it means that the program will not recognize input errors or malformed input (relative to your sequence of scanf calls).本身并不是一个错误,但它意味着程序将无法识别输入错误或格式错误的输入(相对于您的scanf调用序列)。

  • This...这个...

     scanf("%s", &student->fullname);

    ... attempts to read the name into the representation of a pointer. ...尝试将名称读入指针的表示形式。 Undefined behavior results if the name (with terminating null) is longer than the representation of a pointer (probably either four or eight bytes).如果名称(以 null 结尾)长于指针的表示(可能是四个或八个字节),则会导致未定义的行为。 You probably meant to read the data into the location to which the pointer points:您可能打算将数据读入指针指向的位置:

     scanf("%s", student->fullname);

    ... but that is problematic too, because the pointer does not point to valid storage. ...但这也是有问题的,因为指针不指向有效的存储。 You could solve the latter problem (with the corrected code) by declaring the fullname member as an array instead of a pointer, in which case you would want to take care to avoid overrunning the length of that array.您可以通过将fullname名成员声明为数组而不是指针来解决后一个问题(使用更正的代码),在这种情况下,您需要注意避免超出该数组的长度。 Alternatively, you could read the name into a local temporary array, and then allocate a copy for the student to point to:或者,您可以将名称读入本地临时数组,然后为学生分配一个副本以指向:

     char temp[1024]; int result = scanf("%1023s", temp); if (result.= 1) /*... handle input failure..; */; student->fullname = malloc(strlen(temp) + 1), strcpy(student->fullname; temp);

    If you have a POSIX-compatible strdup() function, then you could use that instead of the explicit malloc and strcpy .如果你有一个与 POSIX 兼容的strdup() function,那么你可以使用它来代替显式的mallocstrcpy

  • Also, "fullname" suggests a string that may contain space characters, but %s scans a whitespace-delimited string.此外,“fullname”建议可能包含空格字符的字符串,但%s扫描以空格分隔的字符串。 You may want a %[ directive instead, but do note that that is one of the few directives that does not ignore leading whitespace.您可能需要一个%[指令,但请注意,这是少数几个不忽略前导空格的指令之一。

  • This...这个...

     scanf("%s",&student->ID);

    ... is wrong, because &student->ID is a pointer to int , whereas a %s requires a pointer to char . ... 是错误的,因为&student->ID是指向int的指针,而%s需要指向char的指针。 Additionally, that will attempt to store the result as a string, not as an int .此外,这将尝试将结果存储为字符串,而不是int

  • This...这个...

     scanf("%f",&student[i].scores);

    ... is wrong because you are passing a pointer to an array (of float ), not a pointer to float . ... 是错误的,因为您传递的是指向数组(的float )的指针,而不是指向float的指针。 That in itself probably would not cause an error in practice, but for i != 0 , it is also a pointer to the wrong location.这本身在实践中可能不会导致错误,但对于i != 0 ,它也是指向错误位置的指针。 student[i].scores is the scores array of the student at offset i , but you appear to want the i th element of the scores array of the student at offset 0: student[i].scores是偏移量i处学生的scores数组,但您似乎想要偏移量 0 处学生的分数数组的第i元素:

     scanf("%f", &student->scores[i]);

    An error analogous to this also appears in your output() function.您的output() function 中也会出现与此类似的错误。

    Additionally, if you were checking then you might find that some or all of these calls were failing to scan anything.此外,如果您正在检查,那么您可能会发现这些调用中的一些或全部未能扫描任何内容。 With your current code, this would probably be the case when a three-part fullname was presented (for example, "Cento T. Programmer").使用您当前的代码,可能会出现由三部分组成的全名(例如,“Cento T. Programmer”)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM