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

annefan

New member
שאלת קריאה מקובץ

נתונים: Windows 2000 (אין צורך לשמור על פורטביליות, בכל מקרה ה-API של ספריה שאנ משתמש בה קיים רק ל-WIN). קובץ בינארי, בפורמט ידוע (שלא אני כתבתי, כמובן). השפה היא ++C, כמובן. אני צריך לקרוא אותו לתוך מבנה שייצג אותו כלפי התוכנית שלי. קריאה (ifstream.read, לדוגמא) היא כמובן, רצף של בתים. את הרצף של הבתים, צריך להפוך ל-short, ל-int, ל-long, וכו' לפי הצורך. בשלב ראשון, עשיתי את זה עם union:
union stam { short s; char c[2]; } stam ;​
אני גם יכול לכתוב פונקציות שעושות את זה. השאלה שלי היא האם יש כבר משהו מוכן? (בסטנדרט לא מצאתי. משהו של WINAPI?) תודה!
 

voguemaster

New member
המממף

מנגנוני SERIALIZATION יש ב-MFC, אם אתה יכול להרשות לעצמך לעבוד איתה. עבור WIN32API אני לא מכיר דבר כזה..
 

annefan

New member
כן, ככה זה נראה

Serialzation זה overkill רציני מדי בשביל מה שאני צריך (יש ל-PALM API איזה דפקט שלא יודע לקרוא נתונים כמו שצריך. את הכתיבה הוא עושה מצוין). ב-MFC אני אשתמש ב-GUI. מה שחיפשתי היה פונקציות בסגנון הקונספטואלי של htonl והבני דודים, שלוקחות נתונים בפורמט מסוים ומעבירות לפורמט אחר (נאמר מערך char ל-short) (דומה ל-pack ו-unpack בשפה הכי טובה בעולם...). אם אין, כיוון שאני יודע שהקוד הוא רק Windows (אין בעיות endianess, וגם גדלים קבועים) אני אשתמש ב-union (למרות שזה איכס...).
 

voguemaster

New member
אני אגיד לך מה דעתי בנושא

אני מבין את הקסם שבלהשתמש ב-union למטרה הזו אבל אני אישית לא אוהב את השיטה הזו. זה כמו לבצע parsing לפאקטה מבחינתי. אתה יכול לבצע את זה ע"י union ואתה יכול לבצע את זה ע"י מצביע רץ. אני מעדיף את השיטה השניה כי היא גמישה יותר ומאפשרת לבצע בדיקות תוך כדי ריצה. אין ספק, זה פשוט ביזיון שאין משהו כמו pack ו-unpack ב-C.
 

annefan

New member
לא הסברתי את עצמי טוב

א. אני לא יכול לקרוא את כל הקובץ ולמרוח אותו על כתובת זכרון מסוימת. המבנה של הקובץ הוא דינמי, כך שאני צריך לפחות שני מערכים דינמיים\וקטורים. ב. גם אם הייתי יכול, לא הייתי רוצה לעשות את זה, בגלל בדיקות שצריך לעשות קודם, כמו שאמרת. ג. ה-union שאמרתי, זה רק במקום ערך מסוים שאני חייב לקרוא כרצף בתים, ולהפוך ל-short וכד'.
 

vinney

Well-known member
אני לא חושב שאתה יכול לפתור את זה

באופן ג'נרי. אם מדובר ב++C, אני מציע לך כן להשתמש בSERIALIZATION, או לפחות לכתוב IO למחלקה פרטית שלך, שתעשה את זה. אם זה C, והמבנה ידוע, אז פשוט תקרא בלוק בגודל המבנה לתוך STRUCT שבונה אותו. אחרת - תקרא תו תו ותעשה PARSING, אני לא חושב שיש לך אופציה אחרת, אלא אם כן לחלוטין לא הבנתי את הבעיה
 

annefan

New member
ברור שלא

וכמו שאמרתי אני לא יכול לדעת לפני שאני קורא את הקובץ, מה המבנה המדויק שלו. ממילא האפשרות האחרונה שהעלית היא זו שעשיתי, תוך שימוש ב-union.
 

vinney

Well-known member
אז איך אתה יכול לדעת?

יש לך בתחילת קובץ מזהה כלשהו?
 

annefan

New member
ודאי

הקובץ בנוי כמו עץ רב-בנים, או טבלה. יש לך X משתמשים, ו-Y תוכנות, כשלכל משתמש הגדרות שונות על כל אחת מהתוכנות. בתחילת הקובץ מופיע מספר המשתמשים (מערך דינמי ראשון). איפהשהוא בהמשך הקובץ מופיעות ההגדרות של התוכנות ויש מזהה לסוף הרשימה (אין מספר בקובץ, פשוט צריך לעבור עד תו הסיום). מעבר לזה, יש שתי מחרוזות בגדלים משתנים. בקיצור צריך לעבור על כל הקובץ.
 

vinney

Well-known member
לא בהכרח

אפשר לעשות את זה יותר חכם. תבנה פונקציה אחת שתקרא רשימה עבור משתמש, פונקציה אחרת שתקרא משתמשים, ותשתמש בהן באופן דינמי. אם המחרוזות במקומות קבועים (בין איברי הרשימה או בין רשומות), אין עם זה שום בעיה, צ'יק צ'ק אתה עושה את זה.
 

annefan

New member
מה?

ברור שאפשר לעשות את זה יותר חכם. מה שאתה לא מבין זה שהמחרוזות לא במקומות קבועים, האורך שלהן לא קבוע, ומעבר להן יש עוד את הטבלאות הדינמיות שתיארתי. לא משנה, העקרון ברור. תודה רבה!
 

annefan

New member
אה עוד משהו

כל הקוד הזה, הוא כדי להתגבר על באג של PALM, שלא יכול לקרוא את הנתונים דרך API נורמלי. אני מרכז במחלקה את הקוד, רק כדי להעיף אותו בגירסה הבאה אם הוא יתוקן.
 

voguemaster

New member
תגיד

אתה יודע איך ממומש pack ו-unpack של פרל ? מאוד פשוט - sprintf ו-sscanf. כמובן שהאופציה של פרל חכמה יותר ופשוטה יותר לשימוש וגם מגינה מפני כל מיני בעיות של overflows ו-format strings שמתקבלות משימוש לא נכון בפונקציות של C. אבל בגדול, כך זה מבוצע. אין שום בעיה להשתמש בהן כל עוד זה מבוצע נכון ולא נראה לי שיש לך בעיה בנושא הזה.
 
למעלה