פורסם 2013 במאי 2212 שנים שלום נניח ויש לי קובץ בינארי שניראה כך (כל שורה מייצגת סטראקט) 1 singer1 song1 2 singer2 song2 3 singer3 song3 3 singer3 song3 איך אני מוחק את הסטראקט האחרון כדי שהקובץ יכיל את הנתונים הבאים: 1 singer1 song1 2 singer2 song2 3 singer3 song3 ? נכון לעכשיו למדנו למחוק סטראקט מאמצע הקובץ ע"י דרישה שלו עם הסטראק הבא, כלומר אם היה לנו 1 2 3 4 5 ורצינו למחוק את 3 היינו מגיעים למצב של 1 2 4 4 5 בהתבסס על אותה טכניקה, אני אמור "לדרוס" את הסטראקט האחרון עם EOF נ.ב. חובה לעשות את הכל על קובץ בודד, ללא קבצי עזר נערך 2013 במאי 2212 שנים על-ידי EasyPooper
פורסם 2013 במאי 2212 שנים מחבר נניח ואנחנו עובדים בWINDOWS יש כלי\ספריה\פונקצייה שיכולות לעזור לי? סך הכל זאת מטלת הגשה בקורס סדנה מתקדמת בתכנות, משהו שלומדים סטודנטים למדעי המחשב בשנה הראשונה קשה לי להאמין שהמרצה מצפה מאיתנו "לפלוש" לפונקציות של מערכת ההפלעה התכלית אמורה ליהיות סי... אין דרך כלשהיא "לדרוס" את הסטראקט האחרון עם EOF?
פורסם 2013 במאי 2212 שנים לא. ולמה אתה קורה לזה סטראקט? זו שורה בקובץ.אתה יכול להעתיק את מה שאתה רוצה לקובץ חדש למשל.
פורסם 2013 במאי 2212 שנים מחבר נ.ב.חובה לעשות את הכל על קובץ בודד, ללא קבצי עזרקובץ בינארי, זה הרעיון בו- אוסף של סטראקטים, עם סיומת DAT. או .BIN (לפחות על אלה למדנו עכשיו)אחרי כמה שעות של שיטוטים באינטרנט מצאתי את הפונצייה HANDLE של ווינדואוסוארבעת השורות הבאות אמורות לעשות את העבודה: HANDLE h=CreateFile(L"TEST.$$$",GENERIC_WRITE | GENERIC_READ,0,0,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); // Handle to the file whose file pointer is to be moved. // The file handle must have been created with GENERIC_READ or GENERIC_WRITE // DistanceToMove // lpDistanceToMoveHigh // Pointer to the high-order 32 bits of the signed 64-bit distance to move. // If you do not need the high-order 32 bits, this pointer must be set to NULL // MoveMethod: // FILE_BEGIN, // FILE_CURRENT, // FILE_END SetFilePointer(h,1*sizeof(s),NULL,FILE_BEGIN); SetEndOfFile(h); CloseHandle(h);עכשיו לשכתב כמה מאות שורות קוד כדי שזה יהיה HANDLE זה קצת קשה... יש איזו פקודת המרה?
פורסם 2013 במאי 2212 שנים לא צריך להמיר. פשוט תסגור את הקובץ אחרי שסיימת לעבוד איתו, ואז תפתח אותו מחדש באמצעות הCreateFile רק בשביל לשנות את הגודל.אגב, הHandle זה לא הפונקציה, זה הטיפוס של ה"מצביע" לקובץ, שהפונקציה CreateFile מחזירה. נערך 2013 במאי 2212 שנים על-ידי שניצל
פורסם 2013 במאי 2212 שנים מחבר ככה ניראת פוקנציית המחיקה שלי, שמשום מה לא מוחקת את השורה האחרונה (אבל את ההחלפה בין האיבר הנימחק לאיבר האחרון היא עושה)למישהו יש רעיון מה לא בסדר? { HANDLE h; FILE *f; struct Track tr; f=fopen("Vinyl_List.bin", "r+b"); printf("Deleting\n"); fseek(f,-(sizeof(tr)),SEEK_END); fread(&tr,sizeof(tr),1,f); fseek(f,(sizeof(tr)*(i-1)),SEEK_SET); fwrite(&tr,sizeof(tr),1,f); fseek(f,(sizeof(tr)),SEEK_END); fclose(f); printf("Done Deleting\n");h=CreateFile(L"Vynil_List.bin",GENERIC_WRITE | GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); SetFilePointer(h,-sizeof(tr),NULL,FILE_END); SetEndOfFile(h); CloseHandle(h);void Delete_entry(int i)דא תודה שניצל שהעמדת אותי על דרך הישר ^^ חייתי באשליה קרוב לשעה נערך 2013 במאי 2212 שנים על-ידי EasyPooper
פורסם 2013 במאי 2712 שנים אפשר לעשות זאת ולהסתפק בפונקציות הסטנדרטיות של C בלבד.א. פתח את הקובץ לקריאה, קרא את כולו לזיכרון וסגור אותו. (fopen, fread)ב.מחק, הזז בלוקים וכו' מהזיכרון. (פןנקציות זיכרון memove, memcpy וכו')ג. פתח את הקובץ לכתיבה, וכתוב את הזיכרון הערוך בקובץ (fopen, fwrite)בחיים האמיתיים יש חסרונות לשיטה הזאת כי היא עלולה להרוס את הקובץ המקורי בלי יכולת שיחזור אם לא שומרים גיבוי בצד טרם הפעולה. (חשוב על נפילה של המערכת מיד אחרי שפתחת את הקובץ לקריאה)שנית ייתכן שגודל הקובץ כזה שיקשה עליך לקרוא את כולו לזיכרון.חוץ מזה השיטה צריכה לעבוד.אין דרך סטנדרטית לחתוך קובץ וצריך להשתמש בפונקציות של מערכת ההפעלה על מנת לבצע זאת. בלינוקס/יוניקס יש את הפונקציות truncate ו- ftruncate ובחלונות יש את הפונקציה SetEndOfFile
פורסם 2013 במאי 2712 שנים בחיים האמיתיים לא כותבים לאותו קובץ אלא לקובץ backup ואם הפעולה הצליחה אז מןחקים את המקורי ומשנים שם לגיבוי.בעליית התוכנה אם לא קיים הקובץ הראשי טוענים את הגיבוי.פתרון ממש טריוויאלי לבעיה
פורסם 2013 במאי 2712 שנים אם היית עוקב אחרי הת'רד היית רואה שהוא כבר עשה את כל מה שכתבת...ראיתי ועקבתי, התשובה שלי היתה על מנת להבהיר שאפשר בלי פונקציות שחותכות את הקובץ, כלומר רק פונקציות סטנדרטיות (ובטח לא פונקציות מורכבות כמו CreateFile)בחיים האמיתיים לא כותבים לאותו קובץ אלא לקובץ backup ואם הפעולה הצליחה אז מןחקים את המקורי ומשנים שם לגיבוי.בעליית התוכנה אם לא קיים הקובץ הראשי טוענים את הגיבוי.פתרון ממש טריוויאלי לבעיהנכון, אבל דרישות התרגיל הן ללא קבצים נוספים.
פורסם 2013 במאי 2712 שנים אבל זה אובר-קיל מטורף. אם הקובץ הוא בגודל 1 ג'יגה ואתה רוצה למחוק רשומה בודדת של 10 בתים אז זה ידרוש המון עבודה מיותרת.
פורסם 2013 במאי 2812 שנים אבל זה אובר-קיל מטורף. אם הקובץ הוא בגודל 1 ג'יגה ואתה רוצה למחוק רשומה בודדת של 10 בתים אז זה ידרוש המון עבודה מיותרת.מראש סייגתי שהפתרון שלי לא מתאים למקרי קצה. הוא פשוט מאד ומובן במקרים פשוטים. עבור מקרים יותר מורכבים נצטרך גם פתרון יותר מורכב, זה ברור.
פורסם 2013 ביוני 1612 שנים מחבר תודה רבל לכולם על העזרה! בסוף שעות של שיטוטים באינטרנט מצאתי קטע קוד שעבד שילוב של setendofFile וספריית io.h בC void Delete_entry(int i) { HANDLE h; FILE *f; struct Track tr; f=fopen("Vinyl_List.bin", "r+b"); printf("Deleting\n"); fseek(f,-(sizeof(tr)),SEEK_END); fread(&tr,sizeof(tr),1,f); fseek(f,(sizeof(tr)*(i-1)),SEEK_SET); fwrite(&tr,sizeof(tr),1,f); fseek(f,(sizeof(tr)),SEEK_END); rewind(f); fclose(f); h=(HANDLE)_get_osfhandle(fileno(fopen("Vinyl_List.bin", "r+b"))); SetFilePointer(h,-1*sizeof(tr),NULL,FILE_END); SetEndOfFile(h); CloseHandle(h); printf("Done Deleting\n"); } ככה ניראה הקוד הסופי (שעבד ד"א! ^^) שד"א, משום מה לא עבד עם CREATEFILE שוב תודה לכולם על העזרה, למדתי כמה דברים - - - תגובה אוחדה: - - - אבל זה אובר-קיל מטורף. אם הקובץ הוא בגודל 1 ג'יגה ואתה רוצה למחוק רשומה בודדת של 10 בתים אז זה ידרוש המון עבודה מיותרת. אכן, אוברקיל מטורף... אבל המרצה שלי נוטה לבקש כל מיני מטלות חסרות פואנטה בחיים האמיתיים רק כדי לראות אותנו מתרוצצים ומתאמצים
ארכיון
דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.