[英]Can't print data from struct in C
我的目標是打印struct
中包含的學生數據
我的問題是為什么我無法從結構中打印出數據?
這是我的代碼:
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;
}
這是 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
在 output 功能下,我嘗試打印出一些數據,但沒有一個被打印
我的問題是為什么我無法從結構中打印出數據?
在某種程度上,由於您的input()
function 中有許多錯誤,學生數據並不是您所期望的。 您可以通過在調試器的控制下運行程序來自己發現這一點,並且您的編譯器可能會警告您一些錯誤,至少在您提高警告級別時是這樣。 始終注意編譯器警告。
您的input()
function 的問題包括:
不要fflush()
標准輸入。 沖洗大約是output ,不是輸入。 如果fflush(stdin)
碰巧產生了您認為理想的效果,那么它是不可移植的。 如果您想忽略某些輸入,請閱讀並丟棄它。
但是,只要您使用scanf
或fscanf
進行輸入,請注意大多數字段指令會跳過前導空格,包括換行符。 但是,在這種情況下,還要注意這些功能很難正確使用。 fgets()
結合sscanf()
可能會更好地為您服務,盡管這不是萬能的。
您不檢查scanf()
調用的返回值。 這本身並不是一個錯誤,但它意味着程序將無法識別輸入錯誤或格式錯誤的輸入(相對於您的scanf
調用序列)。
這個...
scanf("%s", &student->fullname);
...嘗試將名稱讀入指針的表示形式。 如果名稱(以 null 結尾)長於指針的表示(可能是四個或八個字節),則會導致未定義的行為。 您可能打算將數據讀入指針指向的位置:
scanf("%s", student->fullname);
...但這也是有問題的,因為指針不指向有效的存儲。 您可以通過將fullname
名成員聲明為數組而不是指針來解決后一個問題(使用更正的代碼),在這種情況下,您需要注意避免超出該數組的長度。 或者,您可以將名稱讀入本地臨時數組,然后為學生分配一個副本以指向:
char temp[1024]; int result = scanf("%1023s", temp); if (result.= 1) /*... handle input failure..; */; student->fullname = malloc(strlen(temp) + 1), strcpy(student->fullname; temp);
如果你有一個與 POSIX 兼容的strdup()
function,那么你可以使用它來代替顯式的malloc
和strcpy
。
此外,“fullname”建議可能包含空格字符的字符串,但%s
掃描以空格分隔的字符串。 您可能需要一個%[
指令,但請注意,這是少數幾個不忽略前導空格的指令之一。
這個...
scanf("%s",&student->ID);
... 是錯誤的,因為&student->ID
是指向int
的指針,而%s
需要指向char
的指針。 此外,這將嘗試將結果存儲為字符串,而不是int
。
這個...
scanf("%f",&student[i].scores);
... 是錯誤的,因為您傳遞的是指向數組(的float
)的指針,而不是指向float
的指針。 這本身在實踐中可能不會導致錯誤,但對於i != 0
,它也是指向錯誤位置的指針。 student[i].scores
是偏移量i
處學生的scores
數組,但您似乎想要偏移量 0 處學生的分數數組的第i
個元素:
scanf("%f", &student->scores[i]);
您的output()
function 中也會出現與此類似的錯誤。
此外,如果您正在檢查,那么您可能會發現這些調用中的一些或全部未能掃描任何內容。 使用您當前的代碼,可能會出現由三部分組成的全名(例如,“Cento T. Programmer”)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.