עבור לתוכן

שפת C - חיפוש בינארי במערך מצביעים למבנה

Featured Replies

פורסם

שלום,

זוהי הפונקציה,ומצורפת גם פונקציית ההשוואה: השאלה שלי בהמשך למטה..

productCompany** companies

הוא מערך מצביעים למבנה מסוג חברה(שם חברה,מספר טלפון וקוד מזהה)

productCompany* SearchCompany(productCompany** companies, int size_company,int search_chose)
{
char* look_for=NULL;
productCompany* found_company ;
int (*compare)(const void* company1,const void* company2);
.....
....
.....
.......
....

fflush(stdin);
gets(look_for);

found_company = bsearch(look_for, companies, size_company, sizeof(productCompany*),compare );//problem!

return found_company;
}

int CompareByName(const void* company1,const void* company2)
{
return strcmp( ( (productCompany*)company1 )->company_name,( (productCompany*)company2 )->company_name );
}

ועכשיו לבעיה.

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

גיליתי שהערך של החיפוש אכן מופיע בקביעות כערך החיפוש בפונקציית ההשוואה,אך הערך השני שאיתו אמורה להיות ההשוואה הוא "זבל" (כל איטרציה זבל אחר).

בקשה עזרה,!!

מה לא בסדר בכתיבת הקוד?

פורסם

הפרמטר הראשון ש-bsearch מקבלת (הערך לחיפוש) צריך להיות מהטיפוס שאתה מחפש. במקרה שלך, אתה מחפש *productCompany, אבל look_for הוא מטיפוס *char. חוץ מזה, found_company צריך להיות מטיפוס **productCompany.

פורסם
  • מחבר

אני מנסה לחפש ע"פ שם - מחרוזת,ועם זה אין בעיה,לא ב look_for, ולא בפונקציית ההשוואה,שכן לערך הראשון שלה(השמאלי) נעשה casting.

ל bsearch אני שולך את הכתובת של תחילת מהערך המצביעים : companies , ואני רוצה ש bsearch תחזיר לי את מצביע למבנה שמכיל

את שם החברה שאותה אני מחפש - look_for. - לכן, לפי הבנתי מצביע למבנה במערך המצביעים ירשם כך: [0]companies, שהוא בעצם מהטיפוס productCompany*

יכול מאוד להיות שאני טועה, אבל הייתי רוצה לבין טיפה יותר מה הולך פה.

תודה

פורסם

אני רואה שבפונקציית ההשוואה שלך אתה עושה casting לשני הערכים, לא רק לראשון.

הבעיה שלך היא שאתה מנסה לחפש מחרוזת בתוך מערך של *productCompany - הפונקציה מנסה להמיר את look_for ל-*productCompany, מה שכמובן לא יעבוד. כמו שאמרתי קודם, הערך שאתה מחפש צריך להיות מאותו טיפוס של הערכים במערך.

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

פורסם

אולי יש טעות עם איזה * או ; אבל זו המחשה ויזואלית:

(ה company בחלק הראשון הכוונה היא ל productCompany)

96913214.png

פורסם
  • מחבר

אהלן טובי,

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

int CompareByName(const void* company1,const void* company2)
{
return strcmp( ( (productCompany*)company1 )->company_name,( (productCompany*)company2 )->company_name );
}

זאת אומרת ל -

( (productCompany*)company2 )->company_name

פורסם

א. תעלה את הקוד המלא.

ב. Pure-Gold אמר שיכול להיות שיש לו טעות עם איזה *, יכול להיות שצריך עוד רמה אחת של מצביעים.

פורסם

תעבוד עם ה Debuger, תשים את כל המשתנים הרלוונטיים ב Watch ותסתכל על הכתובות.

למשל תשים את:

((productCompany*)company1)->company_name
((productCompany*)company2)->company_name

ב watch ותראה שהוא בכלל משווה לך ערכים נכונים.

*תוך כדי תוסיף, תחסיר, תשנה את הקאסטינג שם עד שתקבל את מה שאתה צריך.

פורסם
  • מחבר

מקבל כתובת נכונה תמיד

((productCompany*)company1)->company_name

אבל

((productCompany*)company2)->company_name 

לא..

פורסם

שים לב שהvoid * שאתה מקבל בפונקצייה ההשוואה צריך להיות productCompany** ולא productCompany*. הערך שהמימוש של bsearch נותן לפונקצייה ההשוואה שלך הוא מצביע לאיבר מתוך המערך שנתת לו. הוא לא עושה deref בשום מקום, ולכן אין סיבה שתקבל productCompany*.

בנוסף, כפי ששניצל ציין, הערך הראשון בפונקצייה ההשוואה שלך הוא char* (הערך שנתת לו בקריאה ל- bsearch), ולכן, אתה צריך להמיר אותו ל- char*, ולא ל- productCompany*. יכול להיות שבמקרה קיבלת שם את הערך שהיית צריך בגלל שcompany_name מוגדר כאיבר הראשון ב productCompany.

פורסם
  • מחבר

יש!!

עזרתם לי כולכם, מכל אחד הבנתי קצת וזה הצליח!

תודה

אגב הנה פונקציית ההשוואה הנכונה:

int CompareByName(const void* company1,const void* company2)
{
return strcmp( ((productCompany*)company1)->company_name, (*(productCompany**)company2)->company_name );
}

פורסם

אתה עדיין ממיר את האיבר הראשון שלך ל- productCompany. זו טעות מכיוון שהוא char*.

פורסם
  • מחבר

אתה צודק, אבל גם שיניתי את התכנית שלי, כך שהגדרתי את look_for בתור productCompany**

הקצאתי מקום וקלטתי מחרוזת לתוכו..

פורסם

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

מערך רגיל היה מספיק...

פורסם
  • מחבר

טוסטר,

אני יודע שמערך רגיל היה מספיק,אב לא ממש יעיל..

תחשוב שלכל קריאה לפונקצייה בתכנית הזאת היית צריך לשלוח 1000 מבנים כאלה..לעומת אלף מצביעים

אני טועה?

אגב טוסטר יכול להיות ששמך הוא ארנון ? :)

ארכיון

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

דיונים חדשים