עבור לתוכן

בעיה בהכנסת איברים לרשימה מקושרת

Featured Replies

פורסם

יש לי רשימה מקושרת וקובץ בינארי.

אני צריך להעתיק את התוכן של הרשימה המקושרת (מבנים) אל תוך קובץ בינארי ולא עולה לי איך לעשות את זה

זה סתם נסיון היפוטתי:

void SaveMenu(SList SL,CList CL)
{
SPosition P;

while(SL)
{
P=SL;
if(fwrite(P,sizeof(struct blabla),Scounter,fp1))
{
perror("Can not write to file!");
exit(3);
}
SLAdvance(SL);
}

}

הfp1 אקסטרני. הScounter גם אקסטרני ומטרתו לספור את מספר הצמתים ברשימה (בפונקציה אחרת שבה מזינים לרשימה).

הScounter לא מתקמפל משום מה, אבל אם במקומו אני שם סתם מספר זה מתקמפל אבל עף בfwrite (לא שציפיתי שזה יעבוד)

למישהו יש רעיון (או פונקציה מוכנה) לעשות את זה?

פורסם

אנחנו צריכים את ההגדרות של כל הדברים, וגם את השגיאה שאתה מקבל.

בכל מקרה, מאחר שזה רשימה מקושרת, אני מנחש שאתה רוצה משהו כמו:


int len = sizeof(struct blabla);
SPosition P;

while(SL)
{
P = SL;
if ( fwrite(P, len, 1, fp1) != 1 ) { /* ... */ }
SLAdvance(SL);
}

fwrite מקבלת את גודל הרשומה ואת מספר הרשומות שיש לכתוב לקובץ, ומחזירה את מספר הרשומות שנכתבו בפועל. אם הכל עובד כמו שצריך, מספר זה אמור להיות זהה למספר הרשומות שבקשת לכתוב. מאחר שאתה כותב חוליות של רשימה מקושרת, אז אתה רוצה לכתוב כל פעם חוליה אחת.

הערה: יכול להיות שהתבלבלתי בסדר הפרמטרים, תבדוק.

פורסם
  • מחבר

השגיאות:

12345 error LNK2001: unresolved external symbol _Scounter

12345 fatal error LNK1120: 1 unresolved externals

ההגדרות:

typedef struct student *PtrToStudent;
typedef PtrToStudent SList;
typedef PtrToStudent SPosition;

struct student
{
char Name[LEN];
long ID;
unsigned Age;
char Adress[LEN];
char Gender[LEN];
char Faculty[LEN];
char Status[LEN];
unsigned Year;
unsigned GradesAvg;
unsigned CreditPoints;
SPosition Next;
SPosition CClist;
};

מפוזרים בין הקבצים (בצורה תקינה ומתקמפלת):

extern FILE* fp1;
extern FILE* fp2;
extern Scounter;

פורסם

איפה ואיך הגדרת את Scounter?

בכל מקרה השגיאה היא בזמן הlinkage ולא הקימפול (של הקבצים) ככה שלמרות שהם מתקפלים הלינק לא מצליח.

פורסם

שאלה טיפשית - עשית אינקלוד לקובץ הH?

פורסם
  • מחבר

אז ככה:

extern Scounter;

בקובץ MENUS.C

שבו גם הפונקציה הנ"ל

וגם הפונקציה שבה הוא מאותחל ושמקדמת אותו בהתאם למספר המבנים שמוזנים לרשימה

מחוץ לקובץ הזה אין שימוש בScounter

גם כשאני שם את ה

extern Scounter;

בMENUS.H

זה לא משנה כלום

פורסם

אתה צריך לכתוב באחד מקבצי C שלך:


int Scounter = 0;

פורסם
  • מחבר

עשיתי זאת זה לא עזר.

המשתנה עובד באופן תקין ואפשר לקדם אותו. אבל מקום מה הוא לא רוצה לתפקד בתור משתנה בפונקציה.

פורסם

למה בכלל הוא extern אם אתה משתמש בו רק במודול אחד?

בכל מקרה לפי מה שאתה אומר זה אמור לפעול כי הגדרת משתנה בשם הזה.

אני מציע שתעיף את כל ה-extern-ים, תראה שזה עובד, ואז תחזיר אותם אחד אחד עד שזה עובד.

חוץ מזה מומלץ להצהיר שהוא int. זה לא מקובל להשתמש בטיפוס ברירת המחדל.

פורסם
  • מחבר

מיכוון שבין הפונקציה שמקדמת אותו והפונקציה שמתמשתמשת בו עוברות 4 פונקציות אז אני רוצה שהשינוי שבפונקציה הראשונה יהיה רלווני גם לאחרונה במקום לשרשר את המשתנה הזה בין 10 פונקציות. עשיתי מה שאמרת והבעיה מתחילה רק שאני משתמש בו בqsort

בכל מקרה התייאשתי מה עשיתי את זה בדרך אחרת.

יש לי בעיה אחרת , למה זה עף לי כשאני משתמש בInsertStudent בפעם השניה?

כלומר אני נכנס לcase 1 מכניס רשומה ואז במכניס Y כדי לקבל אפשרות להכניס רשומה נוספת, ואז לאחר שאני מכנסי את הID ולוחץ אנטר זה עף

	switch(x)
{
case '1':
do
{
InsertStudent(P,SL);
printf("\nInsert another student?(Y/N)\n\n");
}while((c=getch())!='N'&&c!='n');
AdministrationMenu(SL,CL);
break;

void InsertStudent(SPosition P,SList SL)
{
ElementType TmpID;
SPosition TmpCell;
char c;
TmpCell = (SPosition) malloc(sizeof(struct student)); // casting
if (TmpCell == NULL)
{
perror("Out of Space!");
exit(1);
}
while(1)
{
printf("Insert ID: "); // זה עף בפעם השניה שאני מגיע לפה
fflush(stdin);
scanf("%lu",&TmpID);
if(!FindStudent(TmpID,SL))
{
TmpCell->ID=TmpID;
break;
}
printf("\nID %lu is allready exist!\n\n",TmpID);
printf("Try again?(Y/N)\n");
if((c=getch())=='N'||c=='n')
exit(0);
}
printf("Insert name: ");
fflush(stdin);
gets(TmpCell->Name);
fflush(stdin);
scanf("%u",&TmpCell->CreditPoints);
TmpCell->Next = P-> Next;
P->Next = TmpCell;
}

פורסם

אולי רצית להשתמש ב- break במקום ב- exit?

פורסם
  • מחבר

כן אבל זה לא קשור לבעיה אני בכלל לא מגיע לexit הזה כי אני בוחר Y

פורסם

בלי להכנס לניתוח של הקוד, לא טיפלת במקרה ש-P או SL הם NULL.

כמו כן יתכן שיש ל-FindStudent תופעות לואי (side effects).

גם שכחת לאתחל שדות ב-TmpCell. השדה CCList חשוד במיוחד.

פורסם
  • מחבר

אני מניח של P וSL תמיד אמיתיים.

CCList בכלל לא משתתף בפונקציה , היא רק מקבלת אותו ולא עושה איתו כלום (בפונקציה הזאת)

מה זאת אומרת לא אתחלתי שדות ב tmpcellהרי זה מה שהפונקציה עושה (פשוט השמטתי אתחולים של חלק מהשדות כדי שלא תהיה ארוכה מידי בהודעה)

גם לי נראה שהבעיה היא ב FindStudent אבל נסתי לגלות מהי אבל היא נראת לי תקינה לגמרי

 SPosition FindStudent(ElementType X, SList L)  
{
SPosition P;
P=L->Next;
if(!P) return 0;
if(P->ID != X)
return FindStudent(X,P->Next);
else
return P;
}

פורסם

1) אני רואה שיש לך הרבה משתנים מקומיים בשם P, שווה לבדוק אם אין לך משנה גלובלי באותו שם.

2) אל תניח שום דבר. תבדוק בכל מקום שצריך אם P או SL (או כל פוינטר שאתה מקבל) הם חוקיים ואינם NULL. קודם שהתוכנית תפעל, אח"כ אם צריך תוריד את הבדיקות. זה נכון שבעתיים כאשר יש לך באג ואין לך מושג איפה - זה בדיוק הזמן להתחיל להכניס בדיקות דביליות.

3) בלולאה הראשית שקוראת ל-InsertStudent, האם זכרת לאתחל את P ואת SL? ואם כן, לאיזה ערכים אתחלת אותם?

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים